Khi mẫu biểu thức được triển khai bằng CRTP, lớp ở đầu hệ thống phân cấp biểu thức sử dụng downcasting từ gốc đến gốc để thực hiện một số thao tác của nó. Theo Clang-3,5 (-std=c++1y
), chăn màn này nên là bất hợp pháp ở constexpr
chức năng:constexpr và CRTP: không đồng bộ trình biên dịch
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)(); }
GCC hạnh phúc compiles the code. Vì vậy, ai đúng? Nếu Clang là đúng, mà C++ 14 hạn chế trên constexpr
chức năng làm cho downcasting bất hợp pháp?
Đây là 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, "");
}
Tôi nghĩ rằng hỏi đang tìm kiếm tài liệu tham khảo tiêu chuẩn. – Columbo
@Columbo Tôi sẽ cố gắng tìm một số. Tuy nhiên, như một quy luật chung nhất (tất cả?) Những thứ mà hành vi không xác định tại thời gian chạy là các lỗi trong các đánh giá 'constexpr'. –
Tôi nghĩ mã là tốt, hãy để tôi có một cái nhìn gần hơn – Columbo