【发布时间】:2015-05-11 16:06:08
【问题描述】:
我有下面的代码,基本上在编译时将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' 的值在常量表达式中不可用
constexpr auto arr = 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);
}
编辑
我正在使用来自 macports 的 g++5.1。使用 clang++ 3.5,即使对于使用 g++ 编译的代码(带有 const 参考),我也会收到错误消息:
错误:const 类型 'const 对象的默认初始化 std::integer_sequence' 需要用户提供的默认值 构造函数
所以我猜缺少用户提供的默认构造函数存在一些问题,但此时我并不真正了解发生了什么。
【问题讨论】:
-
哪个编译器和版本。
-
@ShafikYaghmour g++5.1,很快就会尝试clang。请参阅更新的编辑,即使在通过
const参考传递的情况下,clang++ 也会吐出错误。我可能在常量表达式中遗漏了一些关于 default-ctors 的内容。