c++ - 解析编译错误 : no matching function for call to 'std::pair<,>::pair()'

标签 c++ g++ unordered-map

这是 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. 那么让我们来看看documentation for pair .奇怪的是,那里似乎有一个没有参数的构造函数。

3. 为什么不存在?让我们继续阅读文档:

1) Default constructor. Value-initializes both elements of the pair, first and second.
This constructor participates in overload resolution if and only if std::is_default_constructible_v<first_type> and std::is_default_constructible_v<second_type> are both true. This constructor is explicit if and only if either first_type or second_type is not implicitly default-constructible.



(强调我的)

4. 很好,让我们检查一下情况,first_typesecond_type都是类型 foo在这种情况下。让我们检查一下这种类型:
struct foo {
  int n;
  foo(int n): n(n) {};
  // foo(): n(0) {};
};

有一个foo(int)此类型的构造函数,以及注释掉的 foo()构造函数。应该有一个隐式的默认构造函数,对吧? No:

If no user-declared constructors of any kind are provided for a class type (struct, class, or union), the compiler will always declare a default constructor as an inline public member of its class.



我们有一个 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[] :

Returns a reference to the value that is mapped to a key equivalent to key, performing an insertion if such key does not already exist. ... When the default allocator is used, this results in the key being copy constructed from key and the mapped value being 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()构造函数。这就是我们必须修复它的地方。

结论

仔细阅读错误,查看文档以了解您尚不了解的内容,并跟进您正在使用的功能的要求。并记住向后阅读错误消息以找出错误发生的位置,以及它是在您自己的哪个文件中触发的。然后检查那条线。

关于c++ - 解析编译错误 : no matching function for call to 'std::pair<,>::pair()' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60776989/

相关文章:

c++ - 没有函数模板的实例匹配参数列表我不知道为什么

C++ 类的静态成员在构造函数之后初始化

C++ 错误 std::result_of 没有命名类型

c++ - boost 0 的 unordered_map 键值

c++ - 为什么我不能使用 pair 作为 unordered_set/unordered_map 的键?

c++ - C++ 函数调用中的字符串引用未更新

c++ - 使用 unordered_map 从两个大文本文件中删除重复项

c++ - 调试来自同一代码库的运行时差异

PHP 警告 : PHP Startup: Unable to load dynamic library './lib.so' - ./lib.so: undefined symbol :* 在第 0 行未知

c++ - unordered_map::find() 插入查找的键