C++ 为什么按常量引用传递constexpr对象有效,但按值传递无效';不编译
我有下面的代码,它基本上在编译时将C++ 为什么按常量引用传递constexpr对象有效,但按值传递无效';不编译,c++,c++11,c++14,constexpr,C++,C++11,C++14,Constexpr,我有下面的代码,它基本上在编译时将std::integer_序列映射到std::array: #include <iostream> #include <utility> #include <array> template<int...Is> constexpr auto make_array(const std::integer_sequence<int, Is...>& param) // this works */ //
std::integer_序列
映射到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 << " ";
}
为什么会这样?参数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);
}
#包括
#包括
结构Foo
{
国际货币基金组织;
constexpr Foo(int m):_m(m){};
};
康斯特普富工厂(int m)
{
返回Foo{m};
}
constexpr Foo copy_Foo(Foo Foo)
{
返回foo;
}
int main()
{
constexpr Foo cxfoo=工厂_Foo(42);
constexpr Foo cpfoo=复制_Foo(cxfoo);
}
编辑
我正在使用macports的g++5.1。使用clang++3.5,即使是使用g++编译的代码(使用const
reference),我也会收到一条错误消息:
错误:常量类型为“const”的对象的默认初始化
std::integer_sequence'需要用户提供的默认值
建造师
所以我想,缺少用户提供的默认构造函数可能会有一些问题,但在这一点上,我真的不明白到底发生了什么
如果程序调用
常量合格类型T
,T
应为用户提供的类别类型
默认构造函数
但是,integer\u序列
没有任何用户提供的构造函数,并且constepr
意味着变量的const
,因此在没有初始值设定项的情况下不能定义该类型的constepr
对象。正在添加初始值设定项。iseq上缺少初始值设定项。您必须添加它:
constexpr std::integer_sequence<int, 1,2,3,4> iseq{};
^^
-[结束示例]
此外,正如Columbo在他的和中所指出的,仅仅初始化是不够的。根据[dcl.init],还需要用户提供的构造函数:
如果程序调用常量限定类型的对象的默认初始化,T
,T
应为类类型
使用用户提供的默认构造函数
让最相关的部分(dcl.constepr)对
constepxr
对象声明的要求进行不完整的描述有点奇怪 哪些编译器和版本@ShafikYaghmour g++5.1将很快在clang上试用。参见更新的编辑,clang++即使在通过const
reference的情况下也会出现错误。我可能在常量表达式中遗漏了一些关于默认构造函数的内容。该死!!!!这是一个简单的修复:)那么我猜g++有一个bug。我甚至没有想到只检查iseq
的定义,而clang++可能会因此出错。当我检查隐式常量时看到了这句话+1@Columbo将报告g++的错误(如果还没有报告)@vsoftco首先检查Wandbox上的HEAD.gcc可能允许这样做
constexpr std::integer_sequence<int, 1,2,3,4> iseq{};
^^
struct pixel {
int x, y;
};
constexpr pixel ur = { 1294, 1024 }; // OK
constexpr pixel origin; // error: initializer missing