5

我创建了一个无法用 clang 编译的不可复制的地图。由于 clang 意味着非常符合标准,我想知道我的代码是否合法。MSVS 2010 和 GCC 4.7 编译此代码时不会出现警告或错误。

附上完整代码:有问题的行是main.

= delete需要为 MSVS 2010 移除

#include <utility>
#include <iostream>
#include <map>

template<typename Key_t, typename Value_t, typename Compare_t = std::less<Key_t> >
class non_copyable_map : public std::map<Key_t,Value_t,Compare_t>
{
  typedef std::map<Key_t,Value_t,Compare_t> BaseType;

  public:
    non_copyable_map() { } 

    non_copyable_map(non_copyable_map&& t) : BaseType(std::move(t)) {}   

    non_copyable_map& operator = (non_copyable_map&& t)
    {   
      if ( this != &t )
      {   
        std::swap<BaseType>(*this,t);
      }   
      return *this;
    }   

  private:
    non_copyable_map(const non_copyable_map&) = delete;
    non_copyable_map& operator = (const non_copyable_map&) = delete;
};

int main(int argc, char* argv[])
{
  non_copyable_map<int, non_copyable_map<int, int> > nestedMap;
  non_copyable_map<int,int> inner;
  inner[3]=4;
  nestedMap[2] = std::move(inner); // THIS LINE CAUSES CLANG PROBLEMS
}

使用时的错误信息clang++-mp-3.1 -std=c++0x -stdlib=libc++ MapOfMaps.cpp是:

In file included from MapOfMaps.cpp:2:
In file included from /usr/include/c++/v1/iostream:40:
In file included from /usr/include/c++/v1/istream:156:
In file included from /usr/include/c++/v1/ostream:134:
In file included from /usr/include/c++/v1/bitset:118:
/usr/include/c++/v1/__bit_reference:26:26: error: no type named '__storage_type' in
      'std::__1::map<int, int, std::__1::less<int>, std::__1::allocator<std::__1::pair<const
      int, int> > >'
    typedef typename _C::__storage_type    __storage_type;
            ~~~~~~~~~~~~~^~~~~~~~~~~~~~
MapOfMaps.cpp:21:25: note: in instantiation of template class
      'std::__1::__bit_reference<std::__1::map<int, int, std::__1::less<int>,
      std::__1::allocator<std::__1::pair<const int, int> > > >' requested here
                                std::swap<BaseType>(*this,t);
                                                    ^
MapOfMaps.cpp:36:15: note: in instantiation of member function 'non_copyable_map<int, int,
      std::__1::less<int> >::operator=' requested here
        nestedMap[2] = std::move(inner);
                     ^
In file included from MapOfMaps.cpp:2:
In file included from /usr/include/c++/v1/iostream:40:
In file included from /usr/include/c++/v1/istream:156:
In file included from /usr/include/c++/v1/ostream:134:
In file included from /usr/include/c++/v1/bitset:118:
/usr/include/c++/v1/__bit_reference:27:26: error: no type named '__storage_pointer' in
      'std::__1::map<int, int, std::__1::less<int>, std::__1::allocator<std::__1::pair<const
      int, int> > >'
    typedef typename _C::__storage_pointer __storage_pointer;
            ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
/usr/include/c++/v1/__bit_reference:33:25: error: no type named '__self' in
      'std::__1::map<int, int, std::__1::less<int>, std::__1::allocator<std::__1::pair<const
      int, int> > >'
    friend typename _C::__self;
           ~~~~~~~~~~~~~^~~~~~
In file included from MapOfMaps.cpp:3:
In file included from /usr/include/c++/v1/map:338:
/usr/include/c++/v1/__tree:1291:14: error: overload resolution selected deleted operator '='
    __pair3_ = _STD::move(__t.__pair3_);
    ~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/v1/__tree:1308:9: note: in instantiation of member function
      'std::__1::__tree<std::__1::pair<int, int>, std::__1::__map_value_compare<int, int,
      std::__1::less<int>, true>, std::__1::allocator<std::__1::pair<int, int> >
      >::__move_assign' requested here
        __move_assign(__t, true_type());
        ^
/usr/include/c++/v1/__tree:1353:5: note: in instantiation of member function
      'std::__1::__tree<std::__1::pair<int, int>, std::__1::__map_value_compare<int, int,
      std::__1::less<int>, true>, std::__1::allocator<std::__1::pair<int, int> >
      >::__move_assign' requested here
    __move_assign(__t, integral_constant<bool,
    ^
/usr/include/c++/v1/map:736:21: note: in instantiation of member function
      'std::__1::__tree<std::__1::pair<int, int>, std::__1::__map_value_compare<int, int,
      std::__1::less<int>, true>, std::__1::allocator<std::__1::pair<int, int> > >::operator='
      requested here
            __tree_ = _STD::move(__m.__tree_);
                    ^
/usr/include/c++/v1/type_traits:2342:9: note: in instantiation of member function
      'std::__1::map<int, int, std::__1::less<int>, std::__1::allocator<std::__1::pair<const
      int, int> > >::operator=' requested here
    __x = _STD::move(__y);
        ^
MapOfMaps.cpp:21:5: note: in instantiation of function template specialization
      'std::__1::swap<std::__1::map<int, int, std::__1::less<int>,
      std::__1::allocator<std::__1::pair<const int, int> > > >' requested here
                                std::swap<BaseType>(*this,t);
                                ^
MapOfMaps.cpp:36:15: note: in instantiation of member function 'non_copyable_map<int, int,
      std::__1::less<int> >::operator=' requested here
        nestedMap[2] = std::move(inner);
                     ^
/usr/include/c++/v1/memory:1918:7: note: candidate function (the implicit copy assignment
      operator) has been explicitly deleted
class __compressed_pair
      ^
4 errors generated.
4

1 回答 1

1

这可能是 clang 或 libc++ 错误(很可能是 libc++)。我不是用树干尖端的工具来复制你的症状。最新的 libc++ 头文件在这里。这有点像在黑暗中拍摄,但试试这个:

    swap(static_cast<BaseType&>(*this),static_cast<BaseType&>(t));

看起来你正在纠结于swap这个<__bit_reference>

template <class _Cp, class _Dp>
_LIBCPP_INLINE_VISIBILITY inline
void
swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT

这与地图无关。它恰好在范围内。

于 2012-02-03T01:09:15.437 回答