gpt4 book ai didi

c++ - 比较两个map::iterators:为什么需要std::pair的拷贝构造函数?

转载 作者:IT老高 更新时间:2023-10-28 22:15:17 30 4
gpt4 key购买 nike

下面非常简单的代码在 C++98 中编译和链接时不会出现警告,但在 C++11 模式下会出现难以理解的编译错误。

#include <map>

struct A {
A(A& ); // <-- const missing
};

int main() {
std::map<int, A> m;
return m.begin() == m.end(); // line 9
}

-std=c++11 的错误是,gcc version 4.9.0 20140302 (experimental) (GCC):

ali@X230:~/tmp$ ~/gcc/install/bin/g++ -std=c++11 cctor.cpp In file included from /home/ali/gcc/install/include/c++/4.9.0/bits/stl_algobase.h:64:0,                 from /home/ali/gcc/install/include/c++/4.9.0/bits/stl_tree.h:61,                 from /home/ali/gcc/install/include/c++/4.9.0/map:60,                 from cctor.cpp:1:/home/ali/gcc/install/include/c++/4.9.0/bits/stl_pair.h: In instantiation of ‘struct std::pair’:cctor.cpp:9:31:   required from here/home/ali/gcc/install/include/c++/4.9.0/bits/stl_pair.h:127:17: error: ‘constexpr std::pair::pair(const std::pair&) [with _T1 = const int; _T2 = A]’ declared to take const reference, but implicit declaration would take non-const       constexpr pair(const pair&) = default;                 ^

with clang version 3.5 (trunk 202594)

ali@X230:~/tmp$ clang++ -Weverything -std=c++11 cctor.cpp In file included from cctor.cpp:1:In file included from /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/map:60:In file included from /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/stl_tree.h:63:In file included from /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/stl_algobase.h:65:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/stl_pair.h:119:17: error: the parameter for this explicitly-defaulted copy constructor is const, but      a member or base requires it to be non-const      constexpr pair(const pair&) = default;                ^cctor.cpp:9:22: note: in instantiation of template class 'std::pair' requested here    return m.begin() == m.end(); // line 9                     ^1 error generated.

I have been looking at the code in bits/stl_tree.h and I don't understand why it is trying to instantiate std::pair.

Why does it need the copy constructor of std::pair in C++11?


Note: the above code was extracted from Equality operator (==) unsupported on map iterators for non-copyable maps.


SOLUTION

There are two unfortunate issues here.

Poor quality error messages: Line 8 should already give a compile error although the error messages are only complaining about line 9 . Getting an error on line 8 would be quite helpful and understanding the real problem would be much easier. I will probably submit a bug report / feature request if this issue is still present in gcc / clang trunk.

The other issue is what ecatmur writes. Consider the following code:

struct A {
A() = default;
A(A& ); // <-- const missing
};

template<class T>
struct B {
B() = default;
B(const B& ) = default;
T t;
};

int main() {
B<A> b;
}

编译失败。即使在任何地方都不需要复制构造函数,它仍然会被实例化,因为它是默认内联的,在类的主体中;这会导致编译错误。这可以通过将复制构造函数移出类的主体来解决:

template<class T>
struct B {
B() = default;
B(const B& );
T t;
};

template <class T>
B<T>::B(const B& ) = default;

然后一切正常。不幸的是,std::pair 有一个默认定义的内联复制构造函数。

最佳答案

std::pair 的复制构造函数在这种情况下不需要,而是因为它在 std: 的声明中默认内联定义: pair,它会随着std::pair本身的实例化自动实例化。

标准库可以提供复制构造函数的非内联默认定义:

template<class _T1, class _T2>
struct pair
{
// ...
constexpr pair(const pair&);
// ...
};
// ...
template<class _T1, class _T2>
constexpr pair<_T1, _T2>::pair(const pair&) = default;

但是这不符合标准的严格字母(第 20.3.2 条),其中复制构造函数是默认内联定义的:

  constexpr pair(const pair&) = default;

关于c++ - 比较两个map::iterators:为什么需要std::pair的拷贝构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22357887/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com