I have the code below, that basically maps an std::integer_sequence<>
into an std::array<>
at compile time:
#include <iostream>
#include <utility>
#include <array>
template<int...Is>
constexpr auto make_array(const std::integer_sequence<int, Is...>& param) // this works */
// constexpr auto make_array(std::integer_sequence<int, Is...> param) // doesn't compile
{
return std::array<int, sizeof...(Is)> {Is...};
}
int main()
{
constexpr std::integer_sequence<int, 1,2,3,4> iseq;
// If I pass by value, error: the value of 'iseq' is not usable in a constant expression
constexpr auto arr = make_array(iseq);
for(auto elem: arr)
std::cout << elem << " ";
}
The code works fine whenever make_array
takes its argument by const
-reference. Whenever I try passing it by value, like in the commented line, it spits an error:
error: the value of 'iseq' is not usable in a constant expression
constexpr auto arr = make_array(iseq);
Why is this? The parameter iseq
is certainly a constant expression, why cannot I pass it to make_array
?
For example, the code below works as expected when passing by value:
#include <iostream>
#include <utility>
struct Foo
{
int _m;
constexpr Foo(int m): _m(m){};
};
constexpr Foo factory_foo(int m)
{
return Foo{m};
}
constexpr Foo copy_foo(Foo foo)
{
return foo;
}
int main()
{
constexpr Foo cxfoo = factory_foo(42);
constexpr Foo cpfoo = copy_foo(cxfoo);
}
EDIT
I'm using g++5.1 from macports. Using clang++ 3.5, I get an error message even for the code that compiles with g++ (with const
reference):
error: default initialization of an object of const type 'const std::integer_sequence' requires a user-provided default constructor
so I guess there is some issue with the lack of a user-provided default constructor, but at this point I don't really understand what's going on.
If a program calls for the default initialization of an object of a const-qualified type
T
,T
shall be a class type with a user-provided default constructor.
However, integer_sequence
does not have any user-provided constructors, and constexpr
implies const
for variables, so you can't define a constexpr
object of that type without an initializer.
Adding an initializer makes it compile on Clang.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With