当前位置: 首页 > 知识库问答 >
问题:

无法使用统一初始化复制std::vector

滕令雪
2023-03-14

以下代码无法在 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构造函数还是另一个构造函数。

似乎没有办法解决这个问题,如果是这种情况,那么你永远不能在模板化代码中使用统一初始化。这将是一个巨大的耻辱。

另一方面,VisualStudio(2012年11月CTP)对此并不抱怨。但是initializer_list支持目前还不是很好,所以可能是个bug。

共有2个答案

翟默
2023-03-14

我看不出有什么理由不让gcc(版本4.8.0 20121111)和clang(版本3.3(主干171007))编译代码。也就是说,“统一初始化”远非统一:在调用构造函数时,肯定会出现不能使用大括号的情况。

弓华茂
2023-03-14

这是LWG 2132,它还不是一个缺陷报告,但有明确的共识(和实施经验)来修复它。该标准规定< code>std::function的构造函数将接受任何类型,因此,如果可行的话,初始化列表构造函数总是优先于其他构造函数,所以您的代码尝试从< code>std::initializer_list构造一个向量

换句话说,问题在于std::function有一个不受约束的模板构造函数,允许从任何类型进行转换。这在你的情况下会导致一个问题,因为初始值设定项列表构造函数在可行的情况下比其他构造函数更可取,而无约束函数构造函数意味着总是可以创建initializer_list

对2132建议的解决方案阻止从不可调用的类型构造< code>std::function,因此初始值设定项列表构造函数不可行,而是调用< code>vector复制构造函数。我为GCC 4.8实现了这个解决方案,它也已经在Clang的libc库中实现了。

 类似资料:
  • 以下节目 使用当前Clang(12.0.0)编译,但不使用当前GCC(11.0.0 20201028)。使用GCC它会产生错误 根据[dcl.init.list/5]和string_view(char const*)构造函数是constepr这一事实,我假设Clang的行为就在这里。 对吗?

  • 考虑以下初始化: 在g 5.2.0中,编译器对falseString发出警告,而对trueString发出错误。 使用clang 3.6-std=c 11时,编译器会对假字符串和真字符串抛出错误。 Q1)为什么的行为不同,即使两个初始化值是相同的类型()? Q2)哪个编译器是正确的,为什么?标准怎么说? 编辑: 错误:从“bool”到“std::string”(又名“basic\u string”

  • 我以前见过这样做,但我不记得如何有效地初始化已知长度的与长度相同的。这里有一个很好的例子: 我已经仔细阅读了这一页关于高级矩阵初始化的内容,但是没有明确解释执行此操作的方法。

  • 显式复制构造函数不允许类似于的东西,并将复制使用强制为。此外,显式复制构造函数也不允许从函数中按值返回对象。然而,我尝试用大括号替换复制初始化,就像这样 我得到的错误(g 5.2) 错误:没有匹配的函数用于调用'Foo::Foo(Foo 或(叮当声) 错误:结构初始值设定项中的元素过多 删除使代码在g下可编译,但clang仍然会失败,并出现相同的错误(感谢@stophen)。这是怎么回事?统一初始

  • 考虑以下代码: 以下是一些引用的标准 拷贝初始化 从cppreference复制引用的初始化 如果object是lvalue表达式,其类型是T或从T派生的,且具有相等或较少CV限定性,则该引用绑定到由lvalue标识的对象或其基类子对象。 如果object是lvalue表达式,其类型隐式转换为T或从T派生的类型,具有相等或较少CV限定性,则考虑源类型及其基类返回lvalue引用的非显式转换函数,并

  • 问题内容: 每当我尝试访问phpMyAdmin时,都会出现以下错误: “ 缺少mbstring扩展名。请检查您的PHP配置。 ” 我在CentOS 7服务器上运行LEMP堆栈。我选择使用PHP 7进行此安装。我在运行早期版本的PHP的相同设置上没有遇到此错误。 即使 mbstring.ini (/etc/php.d/)包含以下内容,也会返回false : 我100%确定mbstring模块已安装在