下面编译和链接的非常简单的代码,而无需用C 98警告,但给出了用C 11模式不可理解的编译错误 .
#include
struct A {
A(A& ); //
};
int main() {
std::map m;
return m.begin() == m.end(); // line 9
}
与 -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 .
Why does it need the copy constructor of std::pair in C++11?
注意:上面的代码从平等运算符(==)不支持的在 Map 上的迭代器不可复制 Map 萃取 .
SOLUTION
这里有两个不幸的问题 .
质量差的错误消息:第8行应该已经给出了编译错误,尽管错误消息只是抱怨第9行 . 在第8行获得错误将非常有帮助,理解真正的问题会容易得多 . 如果gcc / clang trunk中仍然存在此问题,我可能会提交错误报告/功能请求 .
另一个问题是ecatmur写的 . 请考虑以下代码:
struct A {
A() = default;
A(A& ); //
};
template
struct B {
B() = default;
B(const B& ) = default;
T t;
};
int main() {
B b;
}
它无法编译 . 即使不被任何所需要的拷贝构造函数,它仍然实例化,因为它是行内默认,在类的主体;这导致编译错误 . 这可以通过将复制构造函数移出类的主体来修复:
template
struct B {
B() = default;
B(const B& );
T t;
};
template
B::B(const B& ) = default;
一切都好 . 不幸的是, std::pair 有一个默认定义的内联复制构造函数 .