模板依赖 false

yrH*_*Jlb 3 c++ templates language-lawyer c++11

我有一个不能直接使用的类模板,只允许特化。我想用来static_assert显示有意义的错误消息。我不能只输入,static_assert(false, "error");因为false它不依赖于值,即使模板从未使用过,编译器也可能会显示错误消息。

我的解决方案:

template<class>
struct AlwaysFalse : std::false_type{};

#define DEPENDENT_FALSE(arg) AlwaysFalse<decltype(sizeof(arg))>::value

template<class T>
struct Foo{
    static_assert(DEPENDENT_FALSE(T), "You must use specialization!");
};

template<int i>
struct Bar{
    static_assert(DEPENDENT_FALSE(i), "You must use specialization!");
};
Run Code Online (Sandbox Code Playgroud)

但我不确定实现DEPENDENT_FALSE。由于MSVCsizeof(arg)作为模板依赖性表达(不像GCC),不过decltype(sizeof(arg)) 是罚款

有人可以用标准来解释这种行为吗?便携吗?

Bar*_*rry 5

这个:

#define DEPENDENT_FALSE(arg) AlwaysFalse<decltype(sizeof(arg))>::value
Run Code Online (Sandbox Code Playgroud)

实际上并没有依赖decltype(sizeof(arg))is always size_t,它实际上并不arg以任何方式依赖(更广泛地说,这里是一个从不依赖于类型的表达式列表)。由于它是不依赖,编译器是完全能够看到DEPENDENT_FALSE(T)false,只是触发器static_assert

你想要的只是:

#define DEPENDENT_FALSE(arg) AlwaysFalse<decltype(arg)>::value
Run Code Online (Sandbox Code Playgroud)

也就是说,删除sizeof. 现在这依赖。


这不会int直接用于,因为它也不会依赖(decltype(i)只是int,我们现在需要一些依赖于值的东西)。为此,您可以将其包装在一个整数常量中:

template<class T>
struct Foo{
    static_assert(AlwaysFalse<T>::value, "You must use specialization!");
};

template<int i>
struct Bar{
    static_assert(AlwaysFalse<std::integral_constant<int, i>>::value, "You must use specialization!");
};
Run Code Online (Sandbox Code Playgroud)