3

私が持っていると言う

class Value;
class Key;

class MyClass {
  private:
  std::map<Key,Value> my_map;
  ....
}

MyClass メソッドの内部には、次のように my_map の値を反復処理する非常に便利な方法があります。

 for( auto& value: my_map | boost::adaptors::map_values) {
    ...
 }

ただし、基本的に my_map | を出力する MyClass のメソッドが必要です。boost::adaptors::map_values を追加し、MyClass メソッドの外で便利な値の反復を許可します。そのようなメソッドを宣言するにはどうすればよいですか? ある種の擬似コンテナと対応するイテレータを実装する必要がありますか?それともショートカットがありますか?

4

2 に答える 2

1

疑似コンテナーや、boost::iterator_range などのイテレーター アダプターを使用する必要はありません。iterator_range などの適切なアダプターを使用すると、理論的にはより正確で汎用性が高くなり、オブジェクトに適用される最小知識の原則に違反することはありませんが、追加の間接化のため、またはイテレーターが通常シングルパス範囲であり、フォワード範囲ではありません。

したがって、適応範囲を直接使用したい場合は、単純に使用decltypeして、アダプターによって既に返されたイテレーターの型を推測できます。

#include <iostream>
#include <map>

#include <boost/range/adaptor/map.hpp>

class A {
  std::map<int,int> my_map = { {0, 1}, {2, 3} };
public:
  decltype(my_map | boost::adaptors::map_values)
  values() { return my_map | boost::adaptors::map_values; }
};

int main() {
    for (const auto& v : A().values())
        std::cout << "v = " << v << std::endl;
    return 0;
}
/* Output:
v = 1
v = 3
*/

また、公開された値を const メンバー関数にしたい場合は、もう少し複雑です。

class A { 
...
  decltype(const_cast<const std::map<int,int>&>(my_map) | boost::adaptors::map_values)
  values() const { return my_map | boost::adaptors::map_values; }
}
于 2014-01-31T11:02:03.137 に答える