我写了一些类型转换操作符,它们只在类型的子集上下文中有意义。
下面是一个例子explicit virtual operator DataId<float>() const
{
static_assert(std::is_same_v<T, DataId<float>>, "std::is_same_v<T, DataId<float>>");
return data; // T data
}
该类包含一个类型为T=DataId<U>
的对象,其中U=float, int, double, std::string
.
static_assert
似乎要求传递给它创建错误消息的参数是const char*
。
是否有办法在消息中打印T
的类型?
我试过了,但是失败了:
constexpr auto message(
(std::string("std::is_same_v<T=") + typeid(T).name() + ", DataId<float>>").c_str()
);
static_assert<..., message>;
根据https://en.cppreference.com/w/cpp/language/static_assert:
由于消息必须是字符串字面值,因此它不能包含动态信息,甚至不能包含本身不是字符串字面值的常量表达式。特别是它不能包含模板的名称类型参数。
因此,如果明确地说它不能包含模板名,我认为这是不可能的。
消息需要是字符串文字,所以您不能这样做。
更新的gcc/clang也已经输出std::is_same
的类型。(gcc 11/clang 8)
对于不这样做的编译器,使得很难获得真正的类型。
一种可能的解决方法是将其封装在模板中,并使其成为硬错误,然后编译器可能会告诉您实例化的类型。
template<typename T, typename U>
consteval void assert_same(){
static_assert(
std::is_same_v<T, U>
);
}
// usage:
template<typename U>
struct X{
using T = std::vector<U>;
void foo(){
assert_same<T,float>();
}
};
将导致报告
'consteval void assert_same() [with T = XXX; U = XXX]'
的实例化:…
错误:static assertion failed
https://godbolt.org/z/Y7TEhM51f