2017-03-24 9 views
0

C++でのコード化: 特定のリスト内の要素への参照を返す関数があるとします(戻り値の型や関数の動作は変更できません) 。それは私がそのリスト上の特定の要素にイテレータを得ることができることを参照を、返さ経由 は、どのような方法は、ありますか? おかげで、 ロイリスト内の要素への参照によるリストイテレータの取得

+2

参照されたオブジェクトは、リストの一部であることを認識していない – UnholySheep

+2

を見てみましょう['std :: find'](http://en.cppreference.com/w/cpp/algorithm/find)。 –

+0

リスト自体にアクセスできない場合は、いいえ。そうした場合、リスト内の要素を 'std :: find'することができます。 – JBL

答えて

0

リストへのアクセス権を持っている場合のみ。とにかくイテレータを使用しようとしている場合は、これを指定する必要があります。

あなたが与えられた基準に一致するまで、再びリストを反復処理し、反復子によって返された各要素をチェックする必要があります。

0

まあ、それは安全ではないの方法で行うことができ、std::list<T>::iteratorがリストノードへのポインタとして実装されていることを前提としています。基本的には、リストノードを囲むアドレスを取得するために値のアドレスを調整する必要があります。これはイテレータの値になります。

enter image description here

実際のコード(Macのgccと打ち鳴らすと連携):

// Offset may vary for different Ts 
template <typename T> 
std::ptrdiff_t list_node_payload_offset() { 
    std::list<T> lst; 
    lst.push_back(T{}); 
    auto lst_begin = lst.begin(); 
    return reinterpret_cast<uint8_t*>(std::addressof(lst.front())) - 
     *reinterpret_cast<uint8_t**>(std::addressof(lst_begin)); 
} 

#pragma GCC optimize "no-strict-aliasing" 
template <typename T> 
typename std::list<T>::iterator to_list_iterator(T& t) { 
    static const auto offset = list_node_payload_offest<T>(); 
    auto node_address = reinterpret_cast<uint8_t*>(std::addressof(t)) - offset; 
    return *reinterpret_cast<typename std::list<T>::iterator*>(&iter_value); 
} 
#pragma GCC optimize "strict-aliasing" 

On Coliru

関連する問題