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.