1

stl コンテナーを POD 型の reference_wrappers と一緒に使用する場合、次のようなコードは正常に機能します。

int i = 0;
std::vector< boost::reference_wrapper<int> > is;
is.push_back(boost::ref(i));
std::cout << (std::find(is.begin(),is.end(),i)!=is.end()) << std::endl;

ただし、(不自然な例) のような非 POD タイプを使用する場合:

struct Integer
{
 int value;

 bool operator==(const Integer& rhs) const
 {
  return value==rhs.value;
 }

 bool operator!=(const Integer& rhs) const
 {
  return !(*this == rhs);
 }
};

上記の比較演算子を宣言するだけでは十分ではなく、さらに次のように宣言する必要があります。

bool operator==(const boost::reference_wrapper<Integer>& lhs, const Integer& rhs)
{
 return boost::unwrap_ref(lhs)==rhs;
}

そしておそらくまた:

bool operator==(const Integer& lhs, const boost::reference_wrapper<Integer>& rhs)
{
 return lhs==boost::unwrap_ref(rhs);
}

同等のコードを動作させるには:

Integer j = { 0 };
std::vector< boost::reference_wrapper<Integer> > js;
js.push_back(boost::ref(j));
std::cout << (std::find(js.begin(),js.end(),j)!=js.end()) << std::endl;

今、これが本当に意図された方法なのかどうか疑問に思っています。テンプレートなど、より単純なソリューションがあるはずです。

template<class T>
bool operator==(const boost::reference_wrapper<T>& lhs, const T& rhs)
{
 return boost::unwrap_ref(lhs)==rhs;
}

template<class T>
bool operator==(const T& lhs, const boost::reference_wrapper<T>& rhs)
{
 return lhs==boost::unwrap_ref(rhs);
}

reference_wrapper がそのように動作するのには、おそらく十分な理由があります (おそらく、比較演算子のない非 POD 型に対応するため?)。たぶん、すでにエレガントなソリューションがあり、私はそれを見つけていません。

4

1 に答える 1

2

元の比較ルーチンを次のように宣言すると、上記の例は機能しますか?

friend bool operator==(const Integer& lhs, const Integer& rhs)
{
    return lhs.value == rhs.value;
}

friend bool operator!=(const Integer& lhs, const Integer& rhs)
{
    return !(lhs == rhs);
}

クラスでフレンド比較ルーチンを宣言することは、メンバー関数比較ルーチンを宣言することと同じではないことに注意してください。そのため、元のコードでは機能しない場合があります。

于 2010-04-09T23:31:28.717 に答える