Ali*_*Ali 17 c++ gcc clang c++11 std-pair
下面非常简单的代码在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
}
Run Code Online (Sandbox Code Playgroud)
错误-std=c++11是,gcc版本4.9.0 20140302(实验)(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;
^
与clang版本3.5(主干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.
我一直在看代码bits/stl_tree.h,我不明白为什么它试图实例化std::pair.
为什么它需要std::pairC++ 11中的复制构造函数?
注意:上面的代码是从不可复制映射的映射迭代器上不支持的Equality运算符(==)中提取的.
解
这里有两个不幸的问题.
质量差的错误消息:第8行应该已经给出了编译错误,尽管错误消息只是抱怨第9行.在第8行获得错误将非常有帮助,理解真正的问题会容易得多.如果gcc/clang trunk中仍然存在此问题,我可能会提交错误报告/功能请求.
另一个问题是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;
}
Run Code Online (Sandbox Code Playgroud)
它无法编译.即使复制构造函数在任何地方都不需要,它仍然被实例化,因为它在类的主体中是内联的默认值; 这导致编译错误.这可以通过将复制构造函数移出类的主体来修复:
template<class T>
struct B {
B() = default;
B(const B& );
T t;
};
template <class T>
B<T>::B(const B& ) = default;
Run Code Online (Sandbox Code Playgroud)
一切都好.不幸的是,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;
Run Code Online (Sandbox Code Playgroud)
然而,这不符合标准的严格规定(第 20.3.2 条),其中复制构造函数默认定义为内联:
Run Code Online (Sandbox Code Playgroud)constexpr pair(const pair&) = default;
| 归档时间: |
|
| 查看次数: |
3241 次 |
| 最近记录: |