下面的代码基本上是在编译时将一个std::integer_sequence<>映射为一个std::array<>:
#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 << " ";
}每当make_array采用const-reference的参数时,代码就能正常工作。每当我尝试按值传递它(如在注释行中)时,它就会产生一个错误:
错误:“iseq”的值在常量表达式中不可用 make_array(iseq);
为什么会这样呢?参数iseq当然是一个常量表达式,为什么我不能将它传递给make_array?
例如,下面的代码在按值传递时按预期工作:
#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);
}编辑
我正在使用来自macport的g++5.1。使用clang++ 3.5,即使是使用g++编译的代码(使用const引用),也会收到错误消息:
错误:默认初始化类型为“const std::integer_sequence”的对象需要用户提供的默认构造函数。
因此,我想缺少一个用户提供的默认构造函数有一些问题,但在这一点上,我并不真正理解发生了什么。
发布于 2015-05-11 16:19:24
您在iseq上缺少了一个初始化器。你必须加上:
constexpr std::integer_sequence<int, 1,2,3,4> iseq{};
^^来自dcl.constexpr
对象声明中使用的
constexpr说明符将对象声明为const。这样的对象应该具有文字类型,将被初始化为。如果它是由构造函数调用初始化的,则该调用应该是一个常量表达式(5.20)。否则,或者如果在引用声明中使用constexpr说明符,则其初始化程序中出现的每个完整表达式都将是一个常量表达式。[注意:用于转换初始化表达式的每个隐式转换和用于初始化的每个构造函数调用都是这种完整表达式的一部分。-end注记] [例子: 结构像素{ int x,y;};constexpr像素ur ={ 1294,1024 };// OK不变像素原点;//错误:初始化器缺失 -end示例]
此外,正如哥伦布在他的comment和answer中所指出的,简单地初始化是不够的。还需要一个用户提供的构造函数,如dcl.init所示。
如果程序调用const限定类型
T的对象的默认初始化,则T应该是具有T默认构造函数的类类型。
让最相关的部分(dcl.constexpr)对constepxr对象声明的需求进行不完整的描述有点奇怪。
发布于 2015-05-11 16:19:10
如果程序调用const限定类型
T的对象的默认初始化,则T应该是具有用户提供的默认构造函数的类类型。
但是,integer_sequence没有任何用户提供的构造函数,而constexpr为变量提供了const,因此如果没有初始化器,就无法定义该类型的constexpr对象。
添加初始化器makes it compile on Clang。
https://stackoverflow.com/questions/30172483
复制相似问题