Phi*_*ßen 15 c++ clang language-lawyer c++11
我目前的程序被clang拒绝,但是用gcc编译好.它归结为以下简化示例:
struct A {
static constexpr inline int one();
};
inline constexpr int A::one() { return 1; }
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
g ++ 4.7.2编译它没有错误(g++ -std=c++11 -Wall -g -o main example.cpp).clang ++ 3.1拒绝它:
$ clang++ -std=c++11 -Wall -g -o main example.cpp
example.cpp:6:25: error: conflicting types for 'one'
inline constexpr int A::one() { return 1; }
^
example.cpp:3:31: note: previous declaration is here
static constexpr inline int one();
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
我敢打赌,gcc是正确的,并且铿锵有误?该程序应该是合法的C++ 11.
有趣的旁注.如果one在结构中实现,则clang不再抱怨:
struct A {
static constexpr inline int one() { return 1; }
}
Run Code Online (Sandbox Code Playgroud)
gcc也接受这个变种.根据我的理解,两个版本应该根据标准相同.这是一个铿锵的错误还是我错过了什么?
Ric*_*ith 10
这是一个Clang bug(在Clang 3.2中修复).问题是,const在确定函数的重新声明是否与先前的声明匹配时,Clang没有正确处理隐含的影响.考虑:
struct A {
int f(); // #1
constexpr int f() const; // #2 (const is implicit in C++11 and can be omitted)
static constexpr int g(); // #3
};
int A::f() { return 1; } // #4, matches #1
constexpr int A::f() { return 1; } // #5, matches #2, implicitly const
constexpr int A::g() { return 1; } // #6, matches #3, not implicitly const
Run Code Online (Sandbox Code Playgroud)
当将类外声明#5与成员匹配时A,编译器有一个问题:它不知道新声明的类型A::f.如果A::f是非静态成员函数,则其类型为int () const,如果它是静态成员函数,则其类型为int ()(无隐式const).
Clang 3.1并没有完全正确:它假设如果一个constexpr函数是一个成员函数,那么constexpr它就是隐含的const,它允许#4和#5工作,但是#6打破了.Clang 3.2通过两次实现constexpr-implies- const规则来解决这个问题:一次在重新声明匹配中(这样#5被认为是重新声明#2而不是#1,即使它还没有隐含const),并且一旦先前的声明已经有了被选中(将隐式const添加到#5).
尽管该标准没有明确提及constexpr静态成员函数的定义是否允许与其声明分开,但它具有以下constexpr7.1.5p1下构造函数的单独定义示例:
struct pixel {
int x;
int y;
constexpr pixel(int); // OK: declaration
};
constexpr pixel::pixel(int a)
: x(square(a)), y(square(a)) // OK: definition
{ }
Run Code Online (Sandbox Code Playgroud)
所以很明显,constexpr函数可以有单独的声明和定义.同样在7.1.5p1中:
如果函数或函数模板的任何声明都有
constexpr说明符,那么它的所有声明都应该包含说明constexpr符.
这意味着constexpr函数可以具有(多个)非定义声明.
| 归档时间: |
|
| 查看次数: |
2651 次 |
| 最近记录: |