0

I have a Holder class that should expose only the values of its map. I used a transform iterator to do so. It works if I use plain pointer to the type (ClassA*) but not with unique_ptr. I based the following example on this code: transform_iterator compile problem

I'm getting the following error (originating in the begin() function), which let's me think that someone is trying to copy the pair instead of using a reference.

Thanks in advance

error C2248:
'std::unique_ptr<ClassA,std::default_delete<_Ty>>::unique_ptr' :
cannot access private member declared in class
'std::unique_ptr<ClassA,std::default_delete<_Ty>>'

#include <iostream>
#include <map>
#include <functional>
#include <memory>
#include <string>
#include <boost/iterator/transform_iterator.hpp>

struct ClassA
{
    ClassA( const std::string& strName ) : m_strName( strName ) {}
    std::string m_strName;
};

template <typename K, typename V>
const V & get_value(std::pair<K, V> const & p)  { return p.second; }

class Holder
{
    typedef std::map<int, std::unique_ptr< ClassA > > TMap;
    typedef std::unique_ptr< ClassA > UniqueA;
    TMap m_Map;
public:
    Holder()
    {
        UniqueA a( new ClassA( "#2# ") );
        UniqueA b( new ClassA( "#3# ") );
        UniqueA c( new ClassA( "#4# ") );
        m_Map.insert( std::make_pair( 2, std::move( a ) ) );
        m_Map.insert( std::make_pair( 3, std::move( b ) ) );
        m_Map.insert( std::make_pair( 4, std::move( c ) ) );
    }
    typedef std::function< const TMap::mapped_type & (const TMap::value_type &) > F;
    typedef boost::transform_iterator<F, TMap::iterator> transform_iterator;

    transform_iterator begin()
    {
        return boost::make_transform_iterator(m_Map.begin(), &get_value< int, std::unique_ptr< ClassA > >);
    }
    transform_iterator end()
    {
        return boost::make_transform_iterator(m_Map.end(), &get_value< int, std::unique_ptr< ClassA > >);
    }
};

void MyTest()
{
    Holder bla;
    auto s_beg = bla.begin();
    auto s_end = bla.end();
    for( auto t=s_beg; t!=s_end;++t) {
        std::cout << ( *t )->m_strName << std::endl;
    }
}
4

1 回答 1

2

问题是它get_value引用了pair<K,V>,但被传递了对映射值类型的引用,pair<const K,V>. 这需要进行转换,这需要将键和值都复制到新的对中。您收到错误,因为unique_ptr无法复制。

解决方案 1:更改get_value为接受pair<const K,V>对匹配的引用TMap::value_type。这允许函数直接接受对映射值的引用。

解决方案 2:实例化get_valueforconst int而不是int; 这将具有与解决方案 1 相同的效果。

解决方案 3:实例化get_valueforconst unique_ptr &而不是unique_ptr,以便它采用包含对映射值的引用的对。无需复制即可创建此临时对unique_ptr

于 2013-06-04T10:13:03.487 回答