我使用一个类
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
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);
这类似于 使用初始值设定项列表放置向量