C++17中调用std::vector<A>::emplace_back(int,int)为何匹配A(int)
问题分析:std::vector::emplace_back的编译错误原因
先看这段C++17代码:
#include<vector> struct A{}; int main() { std::vector<A>a; a.emplace_back(0, 0); }
第一次编译会出现如下错误:
/usr/include/c++/13/bits/new_allocator.h:187:11: error: new initializer expression list treated as compound expression [-fpermissive] 187 | { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/include/c++/13/bits/new_allocator.h:187:11: error: no matching function for call to ‘A::A(int)’ a.cpp:2:8: note: candidate: ‘constexpr A::A()’ 2 | struct A{}; | ^
编译器报错找不到A::A(int),但明明传了两个参数0,0,这是因为C++的逗号表达式语法陷阱:
当编译器尝试匹配A的构造函数时,发现没有能接收两个int的构造,也没有兼容的其他构造(比如初始化列表构造),这时会退而求其次,把括号里的(0, 0)解析成逗号表达式——逗号表达式会先执行左边的0(无实际效果),返回右边的0,相当于只传递了一个int参数。所以编译器尝试调用A(int),但A只有默认构造函数,因此报错。
当给A添加单参数构造函数后:
#include<vector> struct A{ A(int x) {} }; int main() { std::vector<A>a; a.emplace_back(0, 0); }
编译会出现新错误:
/usr/include/c++/13/bits/new_allocator.h:187:11: error: no matching function for call to ‘A::A(int, int)’ 187 | { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ a.cpp:3:5: note: candidate: ‘A::A(int)’ 3 | A(int x) {} | ^
这次编译器尝试找A::A(int, int),原因是:现在A已有单参数构造,编译器不再需要用逗号表达式的 fallback 解析参数——它会认为你确实想传递两个独立的int参数,因此尝试匹配双参数构造,但A依然没有这个构造,所以报错。
简单总结:
- 无单参数构造时,编译器把双参数解析为逗号表达式,尝试单参数构造
- 有单参数构造时,编译器认为你要传两个参数,尝试双参数构造
内容的提问来源于stack exchange,提问作者nalemy
相关产品推荐
相关产品推荐

