GCC 4.9 constexpr bug的解决方法

时间:2015-01-14 15:16:08

标签: c++ c++11 constexpr gcc4.9

我有以下代码代表一段实际更大的代码:

#include <iostream>
using namespace std;

template<size_t N> class A {
    public:
        static constexpr size_t getN() {return N;}
};

template<size_t N> class B {
    public:
        void print() { cout << "B created: " << N << '\n';}
};

template <class T> class C {
    public:
        void set(T* a) {
            t_ptr = a;
        }

        void create() {
            constexpr int m = t_ptr->getN();
            B<m> b;
            b.print();
        }

    private:
        T* t_ptr;
};

int main() {
   constexpr int n = 2;
   A<n> a;
   C<A<n> > c;
   c.set(&a);
   c.create();
}

使用g++ -o main main.cpp -std=c++11和GCC / G ++ 4.8.3进行编译,收到预期的输出:     B创建:2

但是,使用GCC / G ++ 4.9.1代码无法编译,输出:

main.cpp: In member function ‘void C<T>::create()’:
main.cpp:27:15: error: the value of ‘m’ is not usable in a constant expression
             B<m> b;
               ^
main.cpp:26:27: note: ‘m’ used in its own initializer
             constexpr int m = t_ptr->getN();
                           ^
main.cpp:27:16: error: the value of ‘m’ is not usable in a constant expression
             B<m> b;
                ^
main.cpp:26:27: note: ‘m’ used in its own initializer
             constexpr int m = t_ptr->getN();
                           ^
main.cpp:27:19: error: invalid type in declaration before ‘;’ token
             B<m> b;
                   ^
main.cpp:28:15: error: request for member ‘print’ in ‘b’, which is of non-class type ‘int’
             b.print();
               ^

这是由GCC 4.9中的一个已知错误导致的:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59937,在这个较旧的主题https://gcc.gnu.org/ml/gcc-bugs/2013-11/msg00067.html中,建议使用extern作为解决方法。但是,我无法使此解决方法正常工作。

你能帮助我在GCC 4.9中编译这段代码吗?谢谢!

1 个答案:

答案 0 :(得分:3)

由于this不是constexpr,因此this->t_ptr的访问权限也不是。

clang的错误更有帮助

implicit use of 'this' pointer is only allowed within the
    evaluation of a call to a 'constexpr' member function

参考:

  

N3690 5.19 / 2(强调补充)

     

条件表达式e是核心常量表达式,除非评估e,遵循抽象机器的规则,将评估以下表达式之一:< / p>      

- 这个,除了在一个constexpr函数或一个被评估为的constexpr构造函数   e的一部分;

通过typename调用静态成员函数

constexpr int m = T::getN();