为什么我不能在不显式构造中间对象的情况下使用 std::vector::emplace_back,尽管实例创建不需要中间对象?

问题描述 投票:0回答:1

我使用一个类

OneOrMoreIntHelper
,它既接受单个整数也接受整数的初始值设定项列表,并且非常适合通过单个构造函数构造
Class
的实例。

但是,尝试使用

emplace_back
时会失败。例如,此代码示例无法编译,给出错误消息

没有匹配的函数来调用‘std::vector::emplace_back()’

#include <initializer_list>
#include <vector>

struct OneOrMoreIntHelper {
    OneOrMoreIntHelper(const int value) {}
    OneOrMoreIntHelper(const std::initializer_list<int> &) {}
};

struct Class {
    Class(OneOrMoreIntHelper) {}
};

void foo() {
    Class single_int(0);
    Class list_two_ints({0, 0});

    std::vector<Class> instances;
    // this works fine
    instances.emplace_back(0);
    
    // error: no matching function for call to ‘std::vector::emplace_back()’
    instances.emplace_back({0, 0}); 
    
    // Workaround
    instances.push_back(OneOrMoreIntHelper{0, 0});
}

我已经找到了上面的解决方法,但理想情况下,我希望根本不必实例化

OneOrMoreIntHelper
对象(最后,重点是能够键入
0
而不是
{0}
,所以必须在其他地方输入
OneOrMoreIntHelper{0, 0}
完全达不到目的)。

完整的构建日志:

main.cpp: In function ‘void foo()’:
main.cpp:22:27: error: no matching function for call to ‘std::vector::emplace_back()’
   22 |     instances.emplace_back({0, 0});
      |     ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
In file included from /usr/include/c++/11/vector:72,
                 from main.cpp:2:
/usr/include/c++/11/bits/vector.tcc:109:7: note: candidate: ‘std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {}; _Tp = Class; _Alloc = std::allocator; std::vector<_Tp, _Alloc>::reference = Class&]’
  109 |       vector<_Tp, _Alloc>::
      |       ^~~~~~~~~~~~~~~~~~~
/usr/include/c++/11/bits/vector.tcc:109:7: note:   candidate expects 0 arguments, 1 provided
c++ constructor initializer-list
1个回答
1
投票

instances.emplace_back({0, 0});
失败的原因是
emplace_back
是一个函数模板,你无法从initializer-list推导出它的模板参数。另请参阅为什么我的模板不接受初始值设定项列表。具体来说,这是不可能的,因为这是一个非推导的上下文(请参阅此答案,标题 6)。

但是,你可以写:

instances.emplace_back(std::initializer_list<int>{0, 0});
// or
auto list = {0, 0};
instances.emplace_back(list); 

这类似于 使用初始值设定项列表放置向量

© www.soinside.com 2019 - 2024. All rights reserved.