依赖于模板的错误

Template dependent false

本文关键字:错误 依赖于      更新时间:2023-10-16

我有一个类模板,不能直接使用,只允许专业化。我想使用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!");
};

但我不确定是否实现DEPENDENT_FALSE。因为MSVC不将sizeof(arg)视为依赖于模板的表达式(与GCC不同(,但decltype(sizeof(arg))是可以的。

有人能用标准来解释这种行为吗?它是便携式的吗?

这:

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

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

你想要的只是:

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

也就是说,丢弃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!");
};

也许有以下想法:

template<typename T>
struct AlwaysError
{
AlwaysError<T>()
{
std::cout << T::value << std::endl;
static_assert( T::value, "You must use specialization!");
}
};

template <typename T>
struct Foo: public AlwaysError<Foo<T>>
{
static constexpr bool value = false;
};
template <>
struct Foo<int>{};
int main()
{
//Foo<double> d; // error message as expected
Foo<int> i;  // specialized, compiles!
}

断言消息包含文本以及应该专门化的类型。希望它能有所帮助!

在C++17上工作的解决方案。不幸的是,我只有C++11

template<auto>
constexpr bool dependentFalseHelper(){
return false;
}
template<class>
constexpr bool dependentFalseHelper(){
return false;
}
#define DEPENDENT_FALSE(arg) (dependentFalseHelper<arg>())