我有一个模板基类,子类应该将自己作为模板参数传递。

它看起来有点像这样:

template<typename T>
struct Base {
    constexpr Base(int x) : m_x(x) {}
private:
    int m_x;
};

struct Derived : public Base<Derived>
{
    static const Derived LIFE;
    constexpr Derived(int x) : Base(x) {}
};

const Derived Derived::LIFE = Derived(42);

编译并按预期工作。但现在我想让 Derived::LIFE 成为 constexpr。这甚至可能吗?

我不能只是将它的 const 限定符更改为 constexpr,因为需要在其声明中初始化 constexpr:
test.cpp:10:28: error: constexpr static data member ‘LIFE’ must have an initializer
   static constexpr Derived LIFE;

我无法在那里初始化它,因为 Derived 是一个不完整的类型:
test.cpp:10:45: error: invalid use of incomplete type ‘struct Derived’
   static constexpr Derived LIFE = Derived(42);

我意识到如果 Derived 是一个完整的类型,这个问题就会消失,但在这种特殊情况下,由于与这个问题无关的原因,我非常喜欢自引用模板化基类。

如果我正确理解了 this answer 中的最后一段,听起来至少有一些关于在 future 某个时候改变处理不完整类型的方式的讨论,但这对我现在没有帮助。

有没有人知道在我上面的代码中延迟 LIFE 初始化的某种技巧?

最佳答案

我想你应该使用 lazy initialization 。实际上 Derived 仍然是不完整的类型;因为编译器还不知道它的大小。

所以代码应该是:

struct Derived : public Base<Derived>
{
    constexpr Derived(int x) : Base(x) {}

    static constexpr Derived getLIFE()
    {
        return Derived(34);
    }
};

编辑:
可以使用以下代码段重现相同的 incomplete type 行为:
struct MyStruct
{
    static constexpr int x = sizeof(MyStruct);
};

关于c++ - 由于模板基类,从不完整的类型初始化静态 constexpr,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21008861/

10-11 22:23
查看更多