Самый простой код ниже компилируется и содержит ссылки без предупреждения в С++ 98, но дает непонятную ошибку компиляции в режиме С++ 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 версии 4.9.0 20140302 (экспериментальная) (GCC):
[email protected]:~/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; ^
с clang версии 3.5 (соединительная линия 202594)
[email protected]:~/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.
Я просматриваю код в bits/stl_tree.h
, и я не понимаю, почему он пытается создать экземпляр std::pair
.
Зачем нужен конструктор копирования std::pair
в С++ 11?
Примечание: приведенный выше код был извлечен из оператора Equality (==) неподдерживаемого на итераторах карты для не скопируемых карт.
Решение
Здесь есть две неудачные проблемы.
Сообщения об ошибках низкого качества: строка 8 уже должна давать ошибку компиляции, хотя сообщения об ошибках только жалуются на строку 9. Получение ошибки в строке 8 было бы весьма полезным, и понимание реальной проблемы было бы намного проще. Я, вероятно, отправлю отчет об ошибке/функции, если эта проблема все еще присутствует в магистрали gcc/clang.
Другая проблема - это то, что пишет ecatmur. Рассмотрим следующий код:
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
имеет конструктор встроенной копии по умолчанию.