mardi 26 juillet 2016

C++11 Value class in std::map with private constructors

Here is the simplified version of the class which is stored as value in a map which works fine in VS2008:

class Value{
    friend class FriendClass;
    friend class std::map<std::string, Value>;
    friend struct std::pair<const std::string, Value>;
    friend struct std::pair<std::string, Value>;

    Value() {..}
    Value(Value const& other) {..}

    ... rest members...
};

Code (called from FriendClass, so this can reach constructors) :

std::map<const std::string, Value> map;
map.insert(std::make_pair("x", Value()));

This compiles w/o any error in VS2008, but fails on VS2015/C++11:

file.cpp(178): error C2664: 'std::_Tree_iterator>>> std::_Tree>::insert(std::_Tree_const_iterator>>>,const std::pair &)': cannot convert argument 1 from 'std::pair' to 'std::pair &&'
      with
      [
          _Kty=std::string,
          _Ty=Value,
          _Pr=std::less,
          _Alloc=std::allocator>
      ]
      and
      [
          _Kty=std::string,
          _Ty=Value
      ]
  file.cpp(178): note: Reason: cannot convert from 'std::pair' to 'std::pair'
      with
      [
          _Kty=std::string,
          _Ty=Value
      ]
  file.cpp(178): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

If I make the Value copy constructor public, it compiles fine in VS2015 as well.

But that was private with purpose, and only made available for std::map and std::pair. However, it seems in C++11 additional friend access are also necessary to declare. Which are these?

Thank you.

Aucun commentaire:

Enregistrer un commentaire