c++ - 解析编译错误:没有匹配函数调用 'std::pair<,>::pair()'
问题描述
这是assigning-of-unordered-map-to-pair-of-objects的后续问题。这是一个关于编译器错误解释的问题(而不是重复的问题,因为该问题已经完全回答)。有人问我是否查看了错误,并发布错误,以便其他人可以从理解中受益。这是第一个错误:
#include <bits/stdc++.h>
using namespace std;
struct foo {
int n;
foo(int n): n(n) {};
// foo(): n(0) {};
};
int main(){
unordered_map<int, pair<foo,foo>> m;
m[3] = make_pair(foo(1),foo(2));
}
这是编译后的第一个错误(暂时省略其余部分):
g++ -std=c++17 -Weffc++ -Wall -Wextra -Wsign-conversion pairs.cpp -o ../build/pairs.bin
In file included from /usr/include/c++/8/functional:54,
from /usr/include/x86_64-linux-gnu/c++/8/bits/stdc++.h:71,
from pairs.cpp:1:
/usr/include/c++/8/tuple: In instantiation of ‘std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {int&&}; long unsigned int ..._Indexes1 = {0}; _Args2 = {}; long unsigned int ..._Indexes2 = {}; _T1 = const int; _T2 = std::pair<foo, foo>]’:
/usr/include/c++/8/tuple:1657:63: required from ‘std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {int&&}; _Args2 = {}; _T1 = const int; _T2 = std::pair<foo, foo>]’
/usr/include/c++/8/ext/new_allocator.h:136:4: required from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const int, std::pair<foo, foo> >; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Tp = std::__detail::_Hash_node<std::pair<const int, std::pair<foo, foo> >, false>]’
/usr/include/c++/8/bits/alloc_traits.h:475:4: required from ‘static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = std::pair<const int, std::pair<foo, foo> >; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Tp = std::__detail::_Hash_node<std::pair<const int, std::pair<foo, foo> >, false>; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<std::__detail::_Hash_node<std::pair<const int, std::pair<foo, foo> >, false> >]’
/usr/include/c++/8/bits/hashtable_policy.h:2093:36: required from ‘std::__detail::_Hashtable_alloc<_NodeAlloc>::__node_type* std::__detail::_Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _NodeAlloc = std::allocator<std::__detail::_Hash_node<std::pair<const int, std::pair<foo, foo> >, false> >; std::__detail::_Hashtable_alloc<_NodeAlloc>::__node_type = std::__detail::_Hash_node<std::pair<const int, std::pair<foo, foo> >, false>]’
/usr/include/c++/8/bits/hashtable_policy.h:736:8: required from ‘std::__detail::_Map_base<_Key, _Pair, _Alloc, std::__detail::_Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::mapped_type& std::__detail::_Map_base<_Key, _Pair, _Alloc, std::__detail::_Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::operator[](std::__detail::_Map_base<_Key, _Pair, _Alloc, std::__detail::_Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::key_type&&) [with _Key = int; _Pair = std::pair<const int, std::pair<foo, foo> >; _Alloc = std::allocator<std::pair<const int, std::pair<foo, foo> > >; _Equal = std::equal_to<int>; _H1 = std::hash<int>; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<false, false, true>; std::__detail::_Map_base<_Key, _Pair, _Alloc, std::__detail::_Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::mapped_type = std::pair<foo, foo>; std::__detail::_Map_base<_Key, _Pair, _Alloc, std::__detail::_Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::key_type = int]’
/usr/include/c++/8/bits/unordered_map.h:978:20: required from ‘std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type& std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type&&) [with _Key = int; _Tp = std::pair<foo, foo>; _Hash = std::hash<int>; _Pred = std::equal_to<int>; _Alloc = std::allocator<std::pair<const int, std::pair<foo, foo> > >; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type = std::pair<foo, foo>; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type = int]’
pairs.cpp:11:6: required from here
/usr/include/c++/8/tuple:1668:70: error: no matching function for call to ‘std::pair<foo, foo>::pair()’
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
解决方案
通常尝试向后阅读这些错误消息。
1.查看最后一行(分解以更好地适应可用空间)
/usr/include/c++/8/tuple:1668:70: error: no matching function for call
to ‘std::pair<foo, foo>::pair()’
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
这会立即告诉您发生了什么:某处有一个调用(我们必须找出它的来源),调用一个不存在的函数。该函数称为
std::pair<foo, foo>::pair()
这是标准库中一种类型的构造函数。具体来说,它是一个没有参数的构造函数。
2.那么让我们看一下pair 的文档。奇怪的是,那里似乎有一个没有参数的构造函数。
3.为什么不存在?让我们继续阅读文档:
1) 默认构造函数。值初始化该对的两个元素,第一个和第二个。当且仅当且 两者都为 true
时, 此构造函数才参与重载决议。当且仅当 first_type 或 second_type 不是隐式可默认构造的,此构造函数才是显式的。std::is_default_constructible_v<first_type>
std::is_default_constructible_v<second_type>
(强调我的)
4.太好了,让我们检查一下条件,first_type
并且second_type
都是foo
这种情况下的类型。让我们检查一下这种类型:
struct foo {
int n;
foo(int n): n(n) {};
// foo(): n(0) {};
};
这种类型有一个foo(int)
构造函数,还有一个注释掉的foo()
构造函数。应该有一个隐式的默认构造函数,对吧?不:
如果没有为类类型(结构、类或联合)提供任何类型的用户声明的构造函数,编译器将始终将默认构造函数声明为其类的内联公共成员。
我们有一个foo(int)
,因此编译器不会自行生成foo()
。啊哈,调用失败是因为该函数确实不存在。
5.好的,但为什么首先调用它?我不记得调用过这样的函数。-> 查看错误中的“下一个”行:
pairs.cpp:11:6: required from here
该行(pairs.cpp 中的第 11 行)内容如下:
m[3] = make_pair(foo(1),foo(2));
6.关于那里调用的第一个函数,文档有什么要说的?std::unordered_map<int,std::pair<foo,foo>>::operator[]
:
返回对映射到与 key 等效的 key 的 value 的引用,如果这样的 key 不存在,则执行插入。...当使用默认分配器时,这会导致 key 是从 key 构造的副本,并且映射的 value 是value-initialized。
7.值初始化是什么意思?
T() (1)
new T () (2)
Class::Class(...) : member() { ... } (3)
T object {}; (4) (since C++11)
T{} (5) (since C++11)
new T {} (6) (since C++11)
Class::Class(...) : member{} { ... } (7) (since C++11)
请记住,T
这是value_type
您的unordered_map
,而 又是pair<foo,foo>
。这看起来很像编译器之前找不到的调用。
8.如果我们想使用std::unordered_map<K,T>::operator[]
,T
最好是值可初始化,例如通过提供T::T()
构造函数。这就是我们必须修复它的地方。
结论
仔细阅读错误,查看文档以了解您不知道的内容并跟进您正在使用的功能的要求。并记住向后阅读错误消息以找出错误发生的位置,以及它是在您自己的哪个文件中触发的。然后检查那条线。
推荐阅读
- powershell - Power Automate 自定义连接器部署
- java - 调用需要 API 级别 26,同时使用 Java 8+ API 脱糖支持
- python - 我希望我的帖子首先显示最新的,但是当我编辑任何帖子时,它会显示在顶部,我只想要最近添加的帖子
- java - jenkins 服务器中的 NonGUIDriver java.lang.IllegalArgumentException 出错
- python - 如何在 Django 中限制 PasswordResetView 的接收者?
- mockito - Mokito - java.lang.NoClassDefFoundError: org/powermock/core/classloader/MockClassLoader
- javascript - 无法将 id 或元素传递给 mongoose 参数
- nestjs - 在异常过滤器中读取异常情况下的响应
- javascript - React Table isLoading 属性
- python - 稍后修改函数