Curiously recurring template pattern (CRTP) with static constexpr in Clang

前端 未结 2 652
轮回少年
轮回少年 2021-02-15 04:11

Consider my simple example below:

#include 

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

class Derive         


        
相关标签:
2条回答
  • 2021-02-15 04:42

    This probably isn't the answer anyone would be looking for, but I solved the problem by adding a third class:

    #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;
    }
    

    It works as desired, but unfortunately it doesn't really have the benefits of CRTP!

    0 讨论(0)
  • 2021-02-15 04:44

    As linked in the comments, Initializing a static constexpr data member of the base class by using a static constexpr data member of the derived class suggests that clang behaviour is standard conformant up to C++14 here. Starting with Clang 3.9, your code compiles successfully with -std=c++1z. An easy possible workaround is to use constexpr functions instead of values:

    #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;
    }
    
    0 讨论(0)
提交回复
热议问题