带有uniqueptr映射的转换迭代器

transform iterator with map of unique_ptr

本文关键字:转换 迭代器 映射 uniqueptr 带有      更新时间:2023-10-16

我有一个Holder类,它应该只公开其映射的值。我使用了一个转换迭代器。如果我使用指向类型(ClassA*(的纯指针,但不使用unique_ptr,它就可以工作。以下示例基于此代码:transform_iterator编译问题

我得到以下错误(源自begin()函数(,让我认为有人试图复制对,而不是使用引用。

提前感谢

错误C2248:
"std::unique_ptr<ClassA,std::default_delete<_Ty>>::unique_ptr":
无法访问类中声明的私有成员
'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;
    }
}

问题是get_value引用了pair<K,V>,但被传递了对映射值类型pair<const K,V>的引用。这需要转换,需要将键和值都复制到一个新的对中。由于无法复制unique_ptr,因此出现错误。

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

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

解决方案3:将get_value实例化为const unique_ptr &,而不是unique_ptr,这样它就获得了一对包含对映射值的引用的映射。可以在不复制unique_ptr的情况下创建该临时对。