如何将类型的名称作为字符串嵌入到static_assert()中?

kfm*_*e04 7 c++ templates static-assert typeid c++11

问题

不构建以下内容,因为该消息不是字符串文字.

template<typename T>
struct Foo
{ 
  Foo() 
  {
    static_assert( is_pod<T>::value, typeid(T).name() );
  }
};
Run Code Online (Sandbox Code Playgroud)

最终,如果我尝试编译,我想要一个失败的消息,如"Bar必须是pod-type" Foo<Bar> fb;.

是否可以在编译期间构建此字符串,如static_assert

Dan*_*rey 5

在编译时无法构建所需的字符串并将其放入消息中,但这在实践中通常不是问题,因为错误消息将包含调用上下文,并且您始终可以为static_assert显示类型的包装器创建包装器在错误消息中:

template< typename T >
void verify_pod()
{
    static_assert( std::is_pod<T>::value, "T is not a POD" );
}
Run Code Online (Sandbox Code Playgroud)

产量

clang++ -std=c++11 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp:7:5: error: static_assert failed "T is not a POD"
    static_assert( std::is_pod<T>::value, "T is not a POD" );
    ^              ~~~~~~~~~~~~~~~~~~~~~
main.cpp:12:5: note: in instantiation of function template specialization 'verify_pod<std::basic_string<char> >' requested here
    verify_pod< std::string >();
    ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

请注意显示note: ...类型std::string(或此处:)的包装器的位置std::basic_string<char>.

实例(Clang)

对于GCC,错误消息也非常好:

main.cpp: In instantiation of 'void verify_pod() [with T = std::basic_string<char>]':
main.cpp:12:31:   required from here
main.cpp:7:5: error: static assertion failed: T is not a POD
     static_assert( std::is_pod<T>::value, "T is not a POD" );
     ^
Run Code Online (Sandbox Code Playgroud)

实例(GCC)

  • 我不知道,与我见过的一些非常难看的错误消息相比,这对我来说相当不错.:) (3认同)
  • @arne不对.实际上,GCC的错误信息甚至更好(恕我直言). (2认同)