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

时间:2014-01-03 11:54:08

标签: c++ templates c++11 typeid static-assert

问题

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

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

最终,如果我尝试编译Foo<Bar> fb;,我想要一条失败的消息,例如“Bar必须是pod类型”。

是否有可能在编译时根据static_assert的要求构建此字符串?

2 个答案:

答案 0 :(得分:5)

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

static_assert

产量

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

请注意显示类型为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. (或此处为note: ...)的包装的std::string

Live example (Clang)

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

std::basic_string<char>

Live example (GCC)

答案 1 :(得分:2)

在内部模板中,您可以获得Daniel Frey具有explained的内容。外部模板,单独使用static_assert是不可能的,但可以在宏和字符串化运算符#的帮助下完成:

#define VERIFY_POD(T) \
    static_assert(std::is_pod<T>::value, #T " must be a pod-type" );

对于带有gcc 4.8.1的struct non_pod { virtual ~non_pod() {} };类型,VERIFY_POD(non_pod)给出了

main.cpp:4:2: error: static assertion failed: non_pod must be a pod-type
  static_assert(std::is_pod<T>::value, #T " must be a pod-type" );
  ^
main.cpp:15:2: note: in expansion of macro 'VERIFY_POD'
  VERIFY_POD(non_pod);

如果您像我一样并且不想在错误消息中看到令牌#T " must be a pod-type",那么您可以在宏定义中添加额外的行:

#define VERIFY_POD(T) \
    static_assert(std::is_pod<T>::value, \
    #T "must be a pod-type" );

有了这个,前面的例子产生:

main.cpp: In function 'int main()':
main.cpp:4:2: error: static assertion failed: non_pod must be a pod-type
  static_assert(std::is_pod<T>::value, \
  ^
main.cpp:14:2: note: in expansion of macro 'VERIFY_POD'
  VERIFY_POD(non_pod);
  ^

当然,错误消息的确切外观取决于编译器。有了clang 3.4,我们得到了

main.cpp:14:5: error: static_assert failed "non_pod must be a pod-type"
    VERIFY_POD(non_pod);
    ^~~~~~~~~~~~~~~~~~~

main.cpp:3:23: note: expanded from macro 'VERIFY_POD'
#define VERIFY_POD(T) \
                      ^
1 error generated.