Когда шаблоны выражений реализованы с использованием CRTP, класс в верхней части иерархии выражений использует базовое преобразование вниз для реализации некоторых своих операций. Согласно лязг-3.5 (-std=c++1y
), это опущенными должно быть незаконным в constexpr
функции:constexpr и CRTP: несогласие компилятора
test.cpp:42:16: error: static_assert expression is not an integral constant expression
static_assert(e() == 0, "");
^~~~~~~~
test.cpp:11:26: note: cannot cast object of dynamic type 'const base<derived>' to type 'const derived'
const noexcept { return static_cast<const Derived&>(*this)(); }
НКУ счастливо compiles the code. Так кто же прав? Если прав Клэнг, какое ограничение C++ 14 на constexpr
делает это затухание незаконным?
Вот MWE:
template <class Derived>
class base
{
public:
constexpr auto operator()()
const noexcept { return static_cast<const Derived&>(*this)(); }
};
class derived : public base<derived>
{
public:
constexpr auto operator()()
const noexcept { return 0; }
};
template <class A, class B>
class expr : public base<expr<A, B>>
{
const A m_a;
const B m_b;
public:
constexpr explicit expr(const A a, const B b)
noexcept : m_a(a), m_b(b) {}
constexpr auto operator()()
const noexcept { return m_a() + m_b(); }
};
template <class D1, class D2>
constexpr auto foo(const base<D1>& d1, const base<D2>& d2)
noexcept { return expr<base<D1>, base<D2>>{d1, d2}; }
int main()
{
constexpr auto d = derived{};
constexpr auto e = foo(d, d);
static_assert(e() == 0, "");
}
Я думаю, что искатель ищет стандартные ссылки. – Columbo
@Columbo Я попытаюсь найти некоторые. Но как правило, большинство (всех?) Вещей, которые являются неопределенным поведением во время выполнения, являются ошибками в оценках 'constexpr'. –
Я думал, что код в порядке, дайте мне поближе посмотреть – Columbo