c++ - Why passing constexpr object by const reference works, but by value doesn't compile -
i have code below, maps std::integer_sequence<>
std::array<>
@ compile time:
#include <iostream> #include <utility> #include <array> template<int...is> constexpr auto make_array(const std::integer_sequence<int, is...>& param) // 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 pass value, error: value of 'iseq' not usable in constant expression constexpr auto arr = make_array(iseq); for(auto elem: arr) std::cout << elem << " "; }
the code works fine whenever make_array
takes argument const
-reference. whenever try passing value, in commented line, spits error:
error: value of 'iseq' not usable in constant expression
constexpr auto arr = make_array(iseq);
why this? parameter iseq
constant expression, why cannot pass make_array
?
for example, code below works expected when passing 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 macports. using clang++ 3.5, error message code compiles g++ (with const
reference):
error: default initialization of object of const type 'const std::integer_sequence' requires user-provided default constructor
so guess there issue lack of user-provided default constructor, @ point don't understand what's going on.
you missing initializer on iseq
. have add it:
constexpr std::integer_sequence<int, 1,2,3,4> iseq{}; ^^
from [dcl.constexpr]:
a
constexpr
specifier used in object declaration declares objectconst
. such object shall have literal type , shall initialized. if initialized constructor call, call shall constant expression (5.20). otherwise, or ifconstexpr
specifier used in reference declaration, every fullexpression appears in initializer shall constant expression. [ note: each implicit conversion used in converting initializer expressions , each constructor call used initialization part of such full-expression. —end note ]
[ example:struct pixel { int x, y; }; constexpr pixel ur = { 1294, 1024 }; // ok constexpr pixel origin; // error: initializer missing
—end example ]
moreover, columbo suggests in comment , answer, being initialized insufficent. user-provided constructor required, per [dcl.init]:
if program calls default initialization of object of const-qualified type
t
,t
shall class type user-provided default constructor.
it's little odd have relevant section (dcl.constexpr) have incomplete description of requirements constepxr
object declaration.
Comments
Post a Comment