7

问题

由于消息不是字符串文字,因此无法构建以下内容。

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

最终,如果我尝试编译Foo<Bar> fb;.

是否可以按照要求在编译时构建此字符串static_assert

4

2 回答 2

6

不可能在编译时构建所需的字符串并将其放入消息中,但这在实践中通常不是问题,因为错误消息将包含调用上下文,您始终可以为您创建一个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::stringstd::basic_string<char>

现场示例(Clang)

For GCC, the error message is also very nice:

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" );
     ^

Live example (GCC)

于 2014-01-03T12:09:34.990 回答
3

Inside templates, you get what Daniel Frey's has explained. Outside templates, this isn't possible with static_assert alone but can be accomplished with the help of a macro and the stringification operator #:

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

For the type struct non_pod { virtual ~non_pod() {} }; with gcc 4.8.1, VERIFY_POD(non_pod) gives

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);

If you're like me and don't want to see the tokens #T " must be a pod-type" in the error message, then you can add an extra line to the macro definition:

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

with this, the previous example yields:

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);
  ^

Of course, the exact look of the error message depends on the compiler. With clang 3.4 we get

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.
于 2014-01-03T13:14:12.853 回答