Я думаю, что в C ++ 14 из constexpr снято больше ограничений. Но согласно N3797 7.1.5 3-пункт:
Определение функции contexpr должно удовлетворять следующим ограничениям:
Я знаю, почему статические переменные продолжительности хранения потоков запрещены, но я не вижу никакой причины, почему ТОЛЬКО допускается определение переменной литерального типа?
Или я не понимаю стандарт.
Я не уверен, но в соответствии со стандартом должны быть созданы следующие ошибки, даже C ++ 14:
struct point{
constexpr point(): x(0), y(0){}
constexpr point(int x_, int y_): x(x_),y(y_){}
constexpr int hypot()const { return x*x + y*y; }
int x,y;
};
constexpr int hypot(int x, int y) {
point p{x,y}; //error, because p - is not literal type.
return p.hypot();
}
// error, because return type is not literal.
constexpr point getPoint(int x, int y) { return {x,y}; }
// error, because parameter is not literal.
constexpr int hypot(point p) { return p.hypot(); }
Q: Если действительно выше ошибки могут произойти, почему эти ограничения не снимаются?
буквальный тип определяется в 3.9 / 10:
Тип это буквальный тип если это:
void
; или жескалярный тип; или же
ссылочный тип; или же
массив литерального типа; или же
тип класса (раздел 9), который имеет все следующие свойства:
у него есть тривиальный деструктор,
это агрегатный тип (8.5.1) или имеет хотя бы один
constexpr
шаблон конструктора или конструктора, который не является конструктором копирования или перемещения, ивсе его нестатические члены-данные и базовые классы имеют энергонезависимые литеральные типы
Итак, ваша структура point
является литеральный тип и ваш пример кода является допустимым C ++ 1y.
Что касается почему constexpr
функции ограничены переменными литерального типа, они являются единственными типами, которые гарантированно интерпретируются во время компиляции.
Других решений пока нет …