Pic*_*ent 10 c++ g++ c++11 clang++
考虑一下简单的C++ 11代码:
template<int N>
struct Foo {};
template <int N>
constexpr int size(const Foo<N>&) { return N; }
template <int N>
void use_size(const Foo<N>& foo) { constexpr int n = size(foo); }
int main()
{
Foo<5> foo;
constexpr int x = size(foo); // works with gcc and clang
// _but_
use_size(foo); // the same statement in the use_size()
// function _only_ works for gcc
}
Run Code Online (Sandbox Code Playgroud)
我可以成功地编译它 g++ -std=c++11 foo.cpp
但是,如果我使用clang ++,clang++ -std=c++11 foo.cpp我会得到
foo.cpp:15:28: error: constexpr variable 'n' must be initialized by a constant expression
void use_size(const Foo<N>& foo) { constexpr int n = size(foo); }
~~~~~^~~~
foo.cpp:23:5: note: in instantiation of function template specialization 'use_size<5>' requested here
use_size(foo); // the same statement in the use_size()
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
(nb:编译器版本.我用g ++版本5.3.1和7.2.1以及clang ++版本3.6.2和5.0.0检查了前一个语句)
我的问题: g ++或clang中哪一个是对的?问题是什么?
我的解释是clang ++是对的,而g ++太宽容了.
我们可以在标准https://isocpp.org/std/the-standard中找到一个接近的例子([expr.const]部分,第126页)(可以下载草稿,注意大PDF!).
constexpr int g(int k) {
constexpr int x = incr(k);
return x;
}
Run Code Online (Sandbox Code Playgroud)
在那里解释说:
错误:incr(k)不是核心常量表达式,因为k的生命周期开始于表达式incr(k)之外
这正是use_size()函数与foo参数发生的情况,即使该size()函数仅使用N模板参数.
template <int N>
constexpr int size(const Foo<N>&) { return N; }
template <int N>
void use_size(const Foo<N>& foo) { constexpr int n = size(foo); }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
423 次 |
| 最近记录: |