为什么C ++允许类型为std :: map而没有默认构造函数而不是std :: pair?

时间:2018-03-12 09:31:49

标签: c++

检查以下C++代码:

#include <string>
#include <map>

class A
{
public:
    A (int a) {};
};

int main()
{

    std::map<std::string, A> p;
    return 0;
}

编译成功。将std::map更改为std::pair

#include <string>
#include <utility>

class A
{
public:
    A (int a) {};
};

int main()
{

    std::pair<std::string, A> p;
    return 0;
}

编译器会抱怨:

$ clang++ test.cpp
In file included from test.cpp:1:
In file included from /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.3.0/../../../../include/c++/7.3.0/string:40:
In file included from /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.3.0/../../../../include/c++/7.3.0/bits/char_traits.h:39:
In file included from /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.3.0/../../../../include/c++/7.3.0/bits/stl_algobase.h:64:
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.3.0/../../../../include/c++/7.3.0/bits/stl_pair.h:219:18: error: no matching
      constructor for initialization of 'A'
      : first(), second() { }
                 ^
test.cpp:13:31: note: in instantiation of member function 'std::pair<std::__cxx11::basic_string<char>, A>::pair'
      requested here
    std::pair<std::string, A> p;
                              ^
test.cpp:7:5: note: candidate constructor not viable: requires single argument 'a', but no arguments were provided
    A (int a) {};
    ^
test.cpp:4:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were
      provided
class A
      ^
1 error generated.

为什么C++允许类型为std::map而不是std::pair而没有默认构造函数?

2 个答案:

答案 0 :(得分:11)

构造时

std::map为空,这意味着它不需要构造A。另一方面,std::pair必须这样做才能完成初始化。

由于两者都是类模板,因此实际只会实例化您使用的成员函数。如果您想查看预期的错误,则需要让地图尝试构建默认的A,例如:

int main()
{
    std::map<std::string, A> p;

    p[""];
}

答案 1 :(得分:4)

差异是由于A不是默认构造的。对案例会立即选择它,因为它将尝试默认构造A实例。

最终地图案例会产生相同的错误。如果你写p["Hello"];

,你可以看到这个
int main()
{
    std::map<std::string, A> p;
    p["Hello"]; // oops - default constructor required here for `A`
}