Есть ли способ, чтобы строка static_assert динамически настраивалась, а затем отображалась?
Я имею в виду что-то вроде:
//pseudo code
static_assert(Check_Range<T>::value, "Value of " + typeof(T) + " type is not so good ;)");
Есть ли способ, чтобы строка static_assert динамически настраивалась, а затем отображалась?
Я имею в виду что-то вроде:
//pseudo code
static_assert(Check_Range<T>::value, "Value of " + typeof(T) + " type is not so good ;)");
Нет, нет.
Однако это не имеет большого значения, потому что static_assert
оцениваются во время компиляции, а в случае ошибки компилятор не только распечатает само сообщение, но также распечатает стек instanciation (в случае шаблоны).
Взгляните на этот синтетический пример в ideone:
#include <iostream>
template <typename T>
struct IsInteger { static bool const value = false; };
template <>
struct IsInteger<int> { static bool const value = true; };
template <typename T>
void DoSomething(T t) {
static_assert(IsInteger<T>::value, // 11
"not an integer");
std::cout << t;
}
int main() {
DoSomething("Hello, World!"); // 18
}
Компилятор не только испускает диагностику, но также испускает полный стек:
prog.cpp: In function 'void DoSomething(T) [with T = const char*]':
prog.cpp:18:30: instantiated from here
prog.cpp:11:3: error: static assertion failed: "not an integer"
Если вы знаете Python или Java и как они печатают стек в случае исключения, он должен быть знаком. На самом деле это даже лучше, потому что вы не только получаете стек вызовов, но также получаете значения аргументов (типы здесь)!
Поэтому динамические сообщения не так необходимы:)
Стандарт определяет второй аргумент static_assert
как строковый литерал, поэтому нет возможности для вычисления там, насколько я могу видеть (кроме макросов препроцессора).
Компилятор может расширить стандарт и разрешить const-выражения соответствующего типа в этой позиции, но я понятия не имею, есть ли какой-либо компилятор.
Как сказал Маттиу, это невозможно, но вы можете получить некоторые функции, которые вы ищете, используя макросы:
#define CHECK_TYPE_RANGE(type)\
static_assert(Check_Range<type>::value, "Value of " #type " type is not so good ;)");
CHECK_TYPE_RANGE(float); // outputs "Value of float type is not so good ;)"