c – 使用均匀初始化无法复制std :: vector>.它是否正确?

前端之家收集整理的这篇文章主要介绍了c – 使用均匀初始化无法复制std :: vector>.它是否正确?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
以下代码不会在GCC 4.7.2或Clang 3.2中编译:
#include <vector>
#include <functional>

int main()
{
   std::vector<std::function<void()>> a;
   std::vector<std::function<void()>> b{a};
}

问题是,编译器将尝试使用initializer_list创建b,当显然它应该只是调用复制构造函数.然而,这似乎是期望的行为,因为标准表示initializer_list构造函数应该优先.

这个代码对其他std :: vector来说可以正常工作,但是对于std ::函数,编译器无法知道你是否需要initializer_list构造函数或者另一个.

看起来似乎没有办法,如果是这种情况,那么你不能在模板化代码中使用均匀的初始化.这将是一个巨大的耻辱.

Visual Studio(2012年11月CTP)另一方面并不抱怨这一点.但是,在这个时候,initializer_list的支持不是很好,所以可能是一个bug.

解决方法

这是 LWG 2132,它还不是缺陷报告,但有明确的共识(和实施经验)来解决它.该标准表示std :: function的构造函数将接受任何类型,因此如果一个initializer-list构造函数是可行的,那么初始化器列表构造函数总是优先于其他构造函数,您的代码会尝试从std :: initializer_list< std :: function&空隙()>>使用从对象a初始化的单个元素.那会导致一个错误,因为虽然可以构造一个std :: function< void()>从产生的对象不可调用.

换句话说,问题是std :: function有一个无约束的模板构造函数,允许任何类型的转换.这在您的情况下会导致问题,因为如果可行,初始化程序列表构造函数优先于其他构造函数,而无约束函数构造函数意味着始终可以创建一个initializer_list< function< void()>>从任何类型,所以初始化器列表构造函数总是可行的.

对2132的建议解决方案阻止从非可调用类型构造std ::函数,因此initializer-list构造函数不可行,而是调用向量复制构造函数. I implemented that resolution for GCC 4.8,它也已经在Clang的libc库中实现了.

猜你在找的C&C++相关文章