这种情况完全类似于noexcept(noexcept(…))。当然,这听起来更像是一件坏事而不是好事,但让我解释一下。我们将从你已经知道的开始:
c++ 11有“noexcept-子句”和“noexcept-表达式”。他们做不同的事情。
noexcept-子句说:“当…(一些条件)”。它继续进行函数声明,接受一个布尔参数,并在声明的函数中引起行为更改。
noexcept表达式说:“编译器,请告诉我(某个表达式)是否为noexcept。”它本身是一个布尔表达式。它对程序的行为没有“副作用”——它只是向编译器询问是/否问题的答案。“这个表达是没有例外吗?”
我们可以在noexcept-子句中嵌套noexcept-表达式,但我们通常认为这样做是不好的风格。
template<class T>
void incr(T t) noexcept(noexcept(++t)); // NOT SO HOT
将noexcept-表达式封装在类型-trait中被认为是更好的风格。
template<class T> inline constexpr bool is_nothrow_incrable_v =
noexcept(++std::declval<T&>()); // BETTER, PART 1
template<class T>
void incr(T t) noexcept(is_nothrow_incrable_v<T>); // BETTER, PART 2
c++ 2a工作草案有“要求-条款”和“要求-表达式”。他们做不同的事情。
A requires-clause says, "This function should participate in overload resolution when... (some condition)." It goes on a function declaration, takes a boolean parameter, and causes a behavioral change in the declared function.
A requires-expression says, "Compiler, please tell me whether (some set of expressions) is well-formed." It is itself a boolean expression. It has no "side effects" on the behavior of the program — it's just asking the compiler for the answer to a yes/no question. "Is this expression well-formed?"
我们可以在require -子句中嵌套require -表达式,但我们通常认为这样做是糟糕的风格。
template<class T>
void incr(T t) requires (requires(T t) { ++t; }); // NOT SO HOT
将需求表达式封装在类型-trait中被认为是更好的风格…
template<class T> inline constexpr bool is_incrable_v =
requires(T t) { ++t; }; // BETTER, PART 1
template<class T>
void incr(T t) requires is_incrable_v<T>; // BETTER, PART 2
...或者在(c++ 2a工作草案)概念中。
template<class T> concept Incrable =
requires(T t) { ++t; }; // BETTER, PART 1
template<class T>
void incr(T t) requires Incrable<T>; // BETTER, PART 2