gpt4 book ai didi

c++ - 为遗留 C 链表接口(interface)提供 C++ 迭代器

转载 作者:行者123 更新时间:2023-11-27 23:30:47 25 4
gpt4 key购买 nike

我有一个 Visual Studo 2008 C++ 应用程序,我试图在其中向遗留 C-API 的链表结构添加迭代器支持。 C 接口(interface)如下所示:

typedef struct _LINKED_LIST_INFO {
struct _LINKED_LIST_INFO* Next;
const char* name;
// more elements. some are fixed-size; others are pointers to other structures.
} LINKED_LIST_INFO;

DWORD GetLinkedList( LINKED_LIST_INFO* pInfo, PULONG pOutBufLen );

我希望能够像这样使用它:

int _tmain( int /*argc*/, _TCHAR* /*argv*/[] )
{
MyLinkedList elements;
for( MyLinkedList::const_iterator it = elements.begin();
it != elements.end();
++it )
{
printf( "Name: %s\r\n", it->Name().c_str() );
}

return 0;
}

所以,我创建了这 3 个类。但是,我的 MyInfoIterator 类的 operator->() 有问题。我无法返回指向 MyInfo 的临时指针,因此出现错误:error C2440: 'return' : cannot convert from 'MyInfo' to 'const MyInfo *'

这个问题有什么好的解决方案?

/// wrap the legacy C structure and provide C++ accessors
class MyInfo
{
public:

MyInfo( const LINKED_LIST_INFO& info ) : elem_( info ) { };

std::string Name() const { return elem_.name; };

private:
/// one element of the linked list
const LINKED_LIST_INFO& elem_;
}; // class MyInfo

namespace detail {

/// buffer to hold the legacy C linked-list
typedef std::vector< BYTE > MyBuffer;

/// iterator support for the legacy C linked-list
class MyInfoIterator
: public std::iterator< std::input_iterator_tag, MyInfo >
{
public:
explicit MyInfoIterator( MyBuffer& list ) : data_( list )
{
elem_ = reinterpret_cast< LINKED_LIST_INFO* >( &data_.front() );
};

MyInfoIterator() : elem_( NULL ) { };

MyInfoIterator& operator++()
{
elem_ = elem_->Next;
return *this;
};

value_type operator*() { return *elem_; };

// error C2440: 'return' : cannot convert from 'MyInfo' to 'const MyInfo *'
const value_type* operator->() { return elem_; };

friend bool operator==( const MyInfoIterator& i,
const MyInfoIterator& j )
{
return i.elem_ == j.elem_;
};

private:

/// linked-list of elements
MyBuffer data_;

/// current position within the element list
LINKED_LIST_INFO* elem_;

}; // class MyInfoIterator

bool operator!=( const MyInfoIterator& i, const MyInfoIterator& j )
{
return !operator==( i, j );
}

}; // namespace detail

/// provide iterator access for the legacy C linked-list API
class MyLinkedList
{
public:
typedef detail::MyInfoIterator const_iterator;

const_iterator begin() const
{
ULONG size = sizeof( LINKED_LIST_INFO );
detail::MyBuffer buffer( size );

DWORD ec = ::GetLinkedList(
reinterpret_cast< LINKED_LIST_INFO* >( &buffer.front() ), &size );
if( ERROR_BUFFER_OVERFLOW == ec )
{
buffer.resize( size );
ec = ::GetLinkedList(
reinterpret_cast< LINKED_LIST_INFO* >( &buffer.front() ), &size );
}

if( ERROR_SUCCESS != ec )
Win32Exception::Throw( ec );

return const_iterator( buffer );
};

const_iterator end() const { return const_iterator(); };

}; // class MyInfo

谢谢,保罗H

编辑:

我无法更改遗留 API 或其关联结构。

编辑2:

我想我有一个可行的解决方案,它保留了我隐藏底层链表实现的意图,并通过返回 static MyInfo 的地址来维护每个类的职责分离。

class MyInfo
{
// ...
protected:
MyInfo() : info_( NULL ) { };
void Set( const LINKED_LIST_INFO* info ) { info_ = info; };
private:
friend MyInfoIterator;
const LINKED_LIST_INFO* info_;
};

const value_type& MyInfoIterator::operator*() const
{
static MyInfo info;
info.Set( elem_ );
return info;
};

const value_type* MyInfoIterator::operator->() const
{
static MyInfo info;
info.Set( elem_ );
return &info;
};

最佳答案

保持简单:

class MyInfoIterator 
: public std::iterator< std::input_iterator_tag, _LINKED_LIST_INFO >
{
_LINKED_LIST_INFO* p;
public;
MyInfoIterator(_LINKED_LIST_INFO* pointer) : p(pointer) {}

[Same as you did]

value_type& operator*() { return *p; }
}

关于c++ - 为遗留 C 链表接口(interface)提供 C++ 迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5597450/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com