GCC 4.9 constexpr 错误的解决方法
Workaround for GCC 4.9 constexpr bug
我有以下一段代码,它代表了一段实际更大的代码:
#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 and in this older thread https://gcc.gnu.org/ml/gcc-bugs/2013-11/msg00067.html 建议使用 extern
作为解决方法。但是,我无法使此解决方法起作用。
你们能帮我在 GCC 4.9 中编译这段代码吗?谢谢!
由于 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 (emphasis added)
A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:
— this, except in a constexpr function or a constexpr constructor that is being evaluated as
part of e;
通过类型名调用静态成员函数有效
constexpr int m = T::getN();
我有以下一段代码,它代表了一段实际更大的代码:
#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 and in this older thread https://gcc.gnu.org/ml/gcc-bugs/2013-11/msg00067.html 建议使用 extern
作为解决方法。但是,我无法使此解决方法起作用。
你们能帮我在 GCC 4.9 中编译这段代码吗?谢谢!
由于 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 (emphasis added)
A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:
— this, except in a constexpr function or a constexpr constructor that is being evaluated as part of e;
通过类型名调用静态成员函数有效
constexpr int m = T::getN();