static_assert 用于 SFINAE 上下文中使用的表达式
static_assert used in expression which is used in SFINAE context
如果我在 SFINAE 的条件中使用 static_assert
,编译器会发出错误并停止。
template < int i>
class X
{
static_assert( i != 4 );
public:
static constexpr bool value = true;
};
template < typename T >
typename std::enable_if< T::value, void>::type Do( )
{
std::cout << "one" << std::endl;
}
template < typename T >
typename std::enable_if< !T::value, void>::type Do( )
{
std::cout << "two" << std::endl;
}
int main()
{
Do<std::true_type>();
Do<std::false_type>();
// ###########
Do<X<1>>();
Do<X<4>>();
}
这是我们应该期望的行为吗?
Is this the behavior we should expect?
是的。静态断言在 X
的实例化中,而不是在模板函数的直接上下文中。所以这不仅仅是替换失败,程序将是错误的。有一个(尽管是非规范的)说明,进一步支持应该是这样的。
[temp.deduct] (with note emphasized)
8 If a substitution results in an invalid type or expression, type
deduction fails. An invalid type or expression is one that would be
ill-formed, with a diagnostic required, if written using the
substituted arguments. [ Note: If no diagnostic is required, the
program is still ill-formed. Access checking is done as part of the
substitution process. — end note ] Only invalid types and expressions
in the immediate context of the function type and its template
parameter types can result in a deduction failure. [ Note: The
substitution into types and expressions can result in effects such as
the instantiation of class template specializations and/or function
template specializations, the generation of implicitly-defined
functions, etc. Such effects are not in the “immediate context” and
can result in the program being ill-formed. — end note ]
在您的特定情况下,使 X
SFINAE 友好也相当简单:
// No static assertion
static constexpr bool value = (i != 4);
甚至
template <int i>
struct X : std::bool_constant< i != 4 >{};
如果我在 SFINAE 的条件中使用 static_assert
,编译器会发出错误并停止。
template < int i>
class X
{
static_assert( i != 4 );
public:
static constexpr bool value = true;
};
template < typename T >
typename std::enable_if< T::value, void>::type Do( )
{
std::cout << "one" << std::endl;
}
template < typename T >
typename std::enable_if< !T::value, void>::type Do( )
{
std::cout << "two" << std::endl;
}
int main()
{
Do<std::true_type>();
Do<std::false_type>();
// ###########
Do<X<1>>();
Do<X<4>>();
}
这是我们应该期望的行为吗?
Is this the behavior we should expect?
是的。静态断言在 X
的实例化中,而不是在模板函数的直接上下文中。所以这不仅仅是替换失败,程序将是错误的。有一个(尽管是非规范的)说明,进一步支持应该是这样的。
[temp.deduct] (with note emphasized)
8 If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed, with a diagnostic required, if written using the substituted arguments. [ Note: If no diagnostic is required, the program is still ill-formed. Access checking is done as part of the substitution process. — end note ] Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure. [ Note: The substitution into types and expressions can result in effects such as the instantiation of class template specializations and/or function template specializations, the generation of implicitly-defined functions, etc. Such effects are not in the “immediate context” and can result in the program being ill-formed. — end note ]
在您的特定情况下,使 X
SFINAE 友好也相当简单:
// No static assertion
static constexpr bool value = (i != 4);
甚至
template <int i>
struct X : std::bool_constant< i != 4 >{};