考虑简单的 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
}
我可以成功编译它g++ -std=c++11 foo.cpp
但是如果我使用 clang++,clang++ -std=c++11 foo.cpp
I get
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.
(注意:编译器版本。我已经使用 g++ 版本 5.3.1 和 7.2.1 以及 clang++ 版本 3.6.2 和 5.0.0 检查了前面的语句)
我的问题:g++ 和 clang 哪个是正确的?问题是什么?
我的解释是clang++ 是对的 and g++ 太宽容了.
我们可以在标准中找到一个接近的示例([expr.const] 部分,第 126 页)https://isocpp.org/std/the-standard https://isocpp.org/std/the-standard(草稿可以下载,注意大PDF! http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4700.pdf ).
constexpr int g(int k) {
constexpr int x = incr(k);
return x;
}
其中解释说:
错误:incr(k) 不是核心常量表达式,因为
k 的生命周期开始于表达式 incr(k) 之外
这正是正在发生的事情use_size()
函数与foo
论点,即使size()
功能only使用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); }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)