c++ - g++ -std=c++0x 的意外编译问题

标签 c++ c++11

在使用 g++ -std=c++0x 进行编译时,我遇到了一些编译问题,将类型 T 的元素推回 vector 。

这是一个最小的例子:

#include <vector>

using namespace std;

class A {
public:
    A() { }

    A& operator=(A &orig) {
        return *this;
    }
};

int main(int argc, char **argv) {
    A a;
    vector<A> b;
    A c = a; // This is fine
    b.push_back(a); // This is not, but only when compiling with -std=c++0x!
    return 0;
}

它用 g++ -Wall -pedantic 编译得很好,但是当用 g++ -Wall -pedantic -std=c++0x 编译时它给出了这个错误:

 In file included from /usr/include/c++/4.4/vector:69,
                 from min.cpp:1:
/usr/include/c++/4.4/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, _Args&& ...) [with _Args = const A&, _Tp = A, _Alloc = std::allocator<A>]’:
/usr/include/c++/4.4/bits/stl_vector.h:741:   instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = A, _Alloc = std::allocator<A>]’
min.cpp:20:   instantiated from here
/usr/include/c++/4.4/bits/vector.tcc:314: error: no match for ‘operator=’ in ‘__position.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = A*, _Container = std::vector<A, std::allocator<A> >]() = ((const A&)((const A*)std::forward [with _Tp = const A&](((const A&)((const A*)__args#0)))))’
min.cpp:11: note: candidates are: A& A::operator=(A&)
In file included from /usr/include/c++/4.4/vector:61,
                 from min.cpp:1:
/usr/include/c++/4.4/bits/stl_algobase.h: In static member function ‘static _BI2 std::__copy_move_backward<true, false, std::random_access_iterator_tag>::__copy_move_b(_BI1, _BI1, _BI2) [with _BI1 = A*, _BI2 = A*]’:
/usr/include/c++/4.4/bits/stl_algobase.h:595:   instantiated from ‘_BI2 std::__copy_move_backward_a(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = A*, _BI2 = A*]’
/usr/include/c++/4.4/bits/stl_algobase.h:605:   instantiated from ‘_BI2 std::__copy_move_backward_a2(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = A*, _BI2 = A*]’
/usr/include/c++/4.4/bits/stl_algobase.h:676:   instantiated from ‘_BI2 std::move_backward(_BI1, _BI1, _BI2) [with _BI1 = A*, _BI2 = A*]’
/usr/include/c++/4.4/bits/vector.tcc:308:   instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, _Args&& ...) [with _Args = const A&, _Tp = A, _Alloc = std::allocator<A>]’
/usr/include/c++/4.4/bits/stl_vector.h:741:   instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = A, _Alloc = std::allocator<A>]’
min.cpp:20:   instantiated from here
/usr/include/c++/4.4/bits/stl_algobase.h:561: error: no match for ‘operator=’ in ‘* -- __result = std::move [with _Tp = A&](((A&)(-- __last)))’
min.cpp:11: note: candidates are: A& A::operator=(A&)

所以它似乎没有找到 A 的正确 operator=。为什么?为什么在我传递 A 时显示 with _Iterator = A*

最佳答案

语言标准对标准容器元素施加的Assignable 要求要求t = u 表达式有效,即使u 是一个常量对象。自 C++98(参见 23.1/4)以来,该要求就是以这种方式定义的

您违反了该要求,因为您的赋值运算符不接受常量对象。这立即意味着您的类 A 不能用作容器元素类型。

为什么它在 C++03 中工作是无关紧要的。它的工作是偶然的。从错误消息中可以明显看出,库的 C++0x 实现使用了一些 C++0x 特定的功能(如 std::move),这就是上述要求的原因玩。但无论如何,C++03 实现(甚至 C++98 实现)也可能无法针对您的 A 进行编译。

你的例子 A c = a; 是无关紧要的,因为它根本不使用赋值运算符(为什么在这里?)。

为了修复错误,您应该通过常量引用或值接受参数。

关于c++ - g++ -std=c++0x 的意外编译问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6090306/

相关文章:

c++ - 分隔符提取出一系列数据

c++ - 强制 cv::Mat 使用 RGB 数据顺序

c++ - 如何从Makefile中识别冗余库?有没有什么工具可以分析库的使用情况?

c++ - 为什么接受没有关键字的依赖模板名称?

c++ - 是否可以将 unique_ptr 存储在 QPairs 的 QList 中?

C++ 映射访问丢弃限定符 (const)

c++ - 我怎样才能最好地在 C++ 中的不完整类型上使用多态性

c - xorg 输入驱动程序

c++ - 为什么这个 float 的总和是四舍五入的?

c++ - C++11 中的异步构造函数