无法复制std :: vector< std :: function< void()>>使用均匀初始化。它是否正确? [英] Can't copy a std::vector<std::function<void ()>> using uniform initialization. Is this correct?

查看:426
本文介绍了无法复制std :: vector< std :: function< void()>>使用均匀初始化。它是否正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码不能在GCC 4.7.2或Clang 3.2中编译:

The following code does not compile in GCC 4.7.2 or Clang 3.2:

#include <vector>
#include <functional>

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


$ b <显然它应该只是调用复制构造函数。然而这似乎是期望的行为,因为标准说,initializer_list构造函数应该优先。

The issue is that the compiler will try to create b using an initializer_list, when clearly it should just be calling the copy constructor. However this seems to be desired behavior because the standard says that initializer_list constructors should take precedence.

这个代码可以正常工作的其他std :: vector,但std: :函数编译器不知道你是否想要initializer_list构造函数或另一个。

This code would work fine for other std::vector, but for a std::function the compiler can't know whether you want the initializer_list constructor or another one.

它似乎没有一个绕过它的方法,如果这是那么你就不能在模板化代码中使用统一的初始化。这将是一个巨大的耻辱。

It doesn't seem like there is a way around it, and if that is the case then you can never use uniform initialization in templated code. Which would be a giant shame.

Visual Studio(2012年11月CTP)另一方面不抱怨这个。

Visual Studio (2012 November CTP) on the other hand doesn't complain about this. But the initializer_list support is not very good in there at the moment, so it might be a bug.

推荐答案

这是 LWG 2132 尚未成为缺陷报告,但有明确的共识(和实现经验)来解决它。标准说, std :: function 的构造函数将接受任何类型,所以因为初始化列表构造函数总是优先于其他构造函数,如果可行,你的代码试图使用从对象初始化的单个元素 a构造来自 std :: initializer_list< std :: function< void()>>> 的向量。那么会导致错误,因为虽然你可以从 a 构造 std :: function< void()>

This is LWG 2132 which is not yet a Defect Report but there's clear consensus (and implementation experience) to fix it. The standard says that std::function's constructor will accept any type, so because an initializer-list constructor is always preferred to other constructors if it's viable, your code tries to construct a vector from an std::initializer_list<std::function<void()>> with a single element initialized from the object a. That then causes an error because although you can construct a std::function<void()> from a the resulting object isn't callable.

换句话说,问题是 std :: function 有一个不受约束的模板构造函数允许从任何类型转换。这会导致你的情况下的一个问题,因为初始化列表构造函数是首选的其他构造函数,如果可行,和不受约束的函数构造函数意味着它总是可以创建一个 initializer_list< function< void()>> ,因此初始化列表构造函数总是可行的。

In other words the issue is that std::function has an unconstrained template constructor allowing conversion from any type. That causes a problem in your case because initializer-list constructors are preferred to other constructors if viable, and the unconstrained function constructor means it's always possible to create an initializer_list<function<void()>> from any type so an initializer-list constructor is always viable.

到2132阻止从不可调用类型构造 std :: function ,所以初始化器列表构造函数是不可行的,并且 code>复制构造函数。 我实现了GCC 4.8的分辨率,它已经在Clang的libc ++库中实现。

The proposed resolution to 2132 prevents constructing a std::function from a non-callable type, so the initializer-list constructor isn't viable and the vector copy constructor is called instead. I implemented that resolution for GCC 4.8, and it's already implemented in Clang's libc++ library too.

这篇关于无法复制std :: vector&lt; std :: function&lt; void()&gt;&gt;使用均匀初始化。它是否正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆