Ho il codice qui sotto, che mappa fondamentalmente una std::integer_sequence<>
in un std::array<>
in fase di compilazione:Perché passando oggetto constexpr da opere di riferimento const, ma dal valore non compilare
#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 << " ";
}
Il codice funziona bene ogni volta make_array
prende la sua argomentazione con il riferimento const
. Ogni volta che provo di passarlo per valore, come nella linea commentato, sputa un errore:
error: the value of 'iseq' is not usable in a constant expression
constexpr auto arr = make_array(iseq);
Perché è questo? Il parametro iseq
è sicuramente un'espressione costante, perché non posso passarlo a make_array
?
Ad esempio, il codice riportato di seguito funziona come previsto quando si passa per valore:
#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
sto usando g ++ 5.1 da MacPorts. Utilizzando clang ++ 3.5, ottengo un messaggio di errore anche per il codice che compila con g ++ (con const
di riferimento):
error: default initialization of an object of const type 'const std::integer_sequence' requires a user-provided default constructor
quindi credo che ci sia qualche problema con la mancanza di un costruttore di default fornita dall'utente, ma a questo punto non capisco davvero cosa sta succedendo.
Quale compilatore e versione/i. –
@ShafikYaghmour g ++ 5.1, proverò a clang presto. Vedi la modifica aggiornata, clang ++ sta sputando un errore anche nel caso di passaggio per riferimento 'const'. Probabilmente mi manca qualcosa sui medici di base in espressioni costanti. – vsoftco