Как вставить имя типа в виде строки в статический 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.