Как вставить имя типа в виде строки в статический assert ()? [дубликат]
этот вопрос уже есть ответ здесь:
следующее не строится, потому что сообщение не является строковым литералом.
template<typename T>
struct Foo
{
Foo()
{
static_assert( is_pod<T>::value, typeid(T).name() );
}
};
в конечном счете, я хотел бы сообщение об ошибке, как "бар должно быть a pod-type", если я попытаюсь скомпилировать Foo<Bar> fb;.
можно ли построить эту строку во время компиляции, как это требуется static_assert?
2 ответов
невозможно создать требуемую строку во время компиляции и поместить ее в сообщение, но это обычно не проблема на практике, поскольку сообщение об ошибке будет содержать вызывающий контекст, и вы всегда можете создать оболочку для вашего 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 (или вот: std::basic_string<char>) это показали.
для 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" );
^
внутри шаблонов, вы получаете то, что Даниель ФрейС объяснил. Вне шаблонов это невозможно с помощью static_assert самостоятельно, но может быть выполнено с помощью макроса и оператора stringification #:
#define VERIFY_POD(T) \
static_assert(std::is_pod<T>::value, #T " must be a pod-type" );
для типа struct non_pod { virtual ~non_pod() {} }; С gcc 4.8.1,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.