C ++ 14:从参数值初始化constexpr变量 [英] C++14: Initializing constexpr variables from parameter values
问题描述
说我有一个可以通过 constexpr
函数返回常量表达式的类:
template< int N>
struct Foo {
constexpr int Bar()const {return N; }
};
如果我想从 Foo :: Bar()<初始化constexpr值, / code>,我应该如何传递
Foo
类型的参数?我已经尝试了这两个,并在每个变量中都使用示例 constexpr
变量来测试其是否可以初始化:
template< int N>
constexpr int ByValue(Foo N f){
constexpr int i = f.Bar();
返回f.Bar();
}
template< int N>
constexpr int ByReference(const Foo N& f){
constexpr int i = f.Bar();
返回f.Bar();
}
constexpr int a = ByValue(Foo< 1> {});
constexpr int b = ByReference(Foo 1 {});
但是clang 3.7在 ByReference
上引发错误而gcc> = 5.1却没有:
从的角度来看,引用没有预先进行的初始化我
:这是一个参数。一旦调用 ByReference
,它就会初始化。
让我们从 i
的声明中删除 constexpr
并考虑整体调用 ByReference
:
template< int N>
constexpr int ByReference(const Foo& f){
int i = f.Bar();
返回i;
}
constexpr int j = ByReference(Foo <0>());
这很好,因为 f
确实有初始化之前。 f
的初始化程序也是一个常量表达式,因为在这种情况下,隐式声明的默认构造函数为 constexpr
(§ 12.1 / 5)。
因此, i
由常量表达式初始化,而调用本身就是常量表达式。
Say I have a class that that can return a constant expression through a constexpr
function:
template<int N>
struct Foo {
constexpr int Bar() const { return N; }
};
If I wanted to initialize constexpr values from Foo::Bar()
, how should I pass a parameter of type Foo
? I've tried these two, with an example constexpr
variable inside of each to test that it can be initialized:
template<int N>
constexpr int ByValue(Foo<N> f) {
constexpr int i = f.Bar();
return f.Bar();
}
template<int N>
constexpr int ByReference(const Foo<N> &f) {
constexpr int i = f.Bar();
return f.Bar();
}
constexpr int a = ByValue(Foo<1>{});
constexpr int b = ByReference(Foo<1>{});
But clang 3.7 raises an error on ByReference
while gcc >=5.1 does not: Live demo
main.cpp:15:25: error: constexpr variable 'i' must be initialized by a constant expression
constexpr int i = f.Bar();
^~~~~~~
main.cpp:22:25: note: in instantiation of function template specialization 'ByReference<1>' requested here
constexpr int b = ByReference(Foo<1>{});
What's the difference between taking a const Foo &
or a plain Foo
, when Bar
is constexpr
either way and returns a valid constant expression?
Which is right and why, GCC or Clang? If available, references to the standard would be appreciated.
§5.20:
The reference does not have a preceding initialization from the point of view of i
, though: It's a parameter. It's initialized once ByReference
is called.
Let's remove the constexpr
from i
's declaration and consider an invocation of ByReference
in its entirety:
template<int N>
constexpr int ByReference(const Foo<N> &f) {
int i = f.Bar();
return i;
}
constexpr int j = ByReference(Foo<0>());
This is fine, since f
does have preceding initialization. The initializer of f
is a constant expression as well, since the implicitly declared default constructor is constexpr
in this case (§12.1/5).
Hence i
is initialized by a constant expression and the invocation is a constant expression itself.
这篇关于C ++ 14:从参数值初始化constexpr变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!