I have written some type conversion operators which only make sense in the context of a subset of types.
An example is below
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
}
This class contains an object of type T=DataId<U>
, where U=float, int, double, std::string
.
static_assert
seems to demand that the argument passed to it to create the error message is a const char*
.
Is there a way to print the type of T
in the message?
I tried, but failed, with this attempt:
constexpr auto message(
(std::string("std::is_same_v<T=") typeid(T).name() ", DataId<float>>").c_str()
);
static_assert<..., message>;
CodePudding user response:
According to https://en.cppreference.com/w/cpp/language/static_assert :
Since message has to be a string literal, it cannot contain dynamic information or even a constant expression that is not a string literal itself. In particular, it cannot contain the name of the template type argument.
So if it's explicitly said that it can't contain the template name, I don't think it can be done.
CodePudding user response:
the message need to be a string literal, so you cannot do it.
Newer gcc/clang already output the types for std::is_same
as well. (gcc 11/clang 8)
For compilers that doesn't do it and make it harder to get the real types.
A possible workaround is wrap it inside a template and make it a hard error, then compiler would probably tell you the instantiated types.
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>();
}
};
would result in a report of
In instantiation of
'consteval void assert_same() [with T = XXX; U = XXX]'
:...
error: static assertion failed
https://godbolt.org/z/Y7TEhM51f