如果我在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>>();
}
这是我们应该期待的行为吗?
答案 0 :(得分:6)
这是我们应该期待的行为吗?
是的。静态断言是在X
的实例中,而不是在模板函数的直接上下文中。因此,它不会仅仅是替换失败,程序会格式错误。有(尽管不是规范性的)注释,应该进一步支持这种方式。
[扣除温度] (强调注释)
8如果替换导致无效的类型或表达式,请键入 推论失败。无效的类型或表达式将是 格式错误,且需要诊断,如果使用 替代参数。 [注意:如果不需要诊断,则 程序仍然格式不正确。访问检查是作为 替代过程。 — end note]仅无效的类型和表达式 在函数类型及其模板的直接上下文中 参数类型可能会导致推导失败。 [注意: 替换为类型和表达式可能会导致诸如 类模板专业化和/或功能的实例化 模板专业化,隐式定义的生成 功能等。此类影响不在“即时上下文”中,并且 可能会导致程序格式错误。 —尾注]
在您的特定情况下,让X
对SFINAE友好也很简单:
// No static assertion
static constexpr bool value = (i != 4);
甚至
template <int i>
struct X : std::bool_constant< i != 4 >{};