【问题标题】:Curiously recurring template pattern (CRTP) with static constexpr in ClangClang 中带有静态 constexpr 的奇怪重复模板模式 (CRTP)
【发布时间】:2016-06-21 15:35:06
【问题描述】:

考虑下面我的简单示例:

#include <iostream>

template <typename T>
class Base
{
public:
    static constexpr int y = T::x;
};

class Derived : public Base<Derived>
{
public:
    static constexpr int x = 5;
};


int main()
{
    std::cout << Derived::y << std::endl;
}

在 g++ 中,这可以正常编译并按预期打印 5。但是,在 Clang 中,它无法编译并出现错误 no member named 'x' in 'Derived'。据我所知,这是正确的代码。我正在做的事情有问题吗,如果没有,有没有办法在 Clang 中进行这项工作?

【问题讨论】:

标签: c++ templates c++11 clang crtp


【解决方案1】:

如 cmets 中所链接,Initializing a static constexpr data member of the base class by using a static constexpr data member of the derived class 表明 clang 行为在此处符合 C++14 标准。从 Clang 3.9 开始,您的代码使用 -std=c++1z 成功编译。 一个简单的解决方法是使用 constexpr 函数而不是值:

#include <iostream>

template <typename T>
class Base
{
public:
    static constexpr int y() {return T::x();}
};

class Derived : public Base<Derived>
{
public:
    static constexpr int x() {return 5;}
};

int main()
{
    std::cout << Derived::y() << std::endl;
}

【讨论】:

    【解决方案2】:

    这可能不是任何人都在寻找的答案,但我通过添加第三个类解决了这个问题:

    #include <iostream>
    
    template <typename T>
    class Base
    {
    public:
        static constexpr int y = T::x;
    };
    
    class Data
    {
    public:
         static constexpr int x = 5;
    };
    
    class Derived : public Base<Data>, public Data {};
    
    int main()
    {
        std::cout << Derived::y << std::endl;
    }
    

    它按预期工作,但不幸的是它并没有真正具有 CRTP 的好处!

    【讨论】:

      猜你喜欢
      • 2022-01-01
      • 1970-01-01
      • 2019-11-18
      • 2013-02-15
      相关资源
      最近更新 更多