2010-04-09 59 views
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類型,而比較運算符?)。也許已經有一個優雅的解決方案,我只是沒有找到它。

+1

將非成員函數用於成員函數。這種情況就是這樣一個原因。當它是成員函數時,操作符*要求*左側是特定類型。相反,當它是一個自由函數時,它可以在任何可轉換爲'reference_wrapper'參數的類型上被調用。 – GManNickG 2010-04-09 23:37:57

+0

@GMan:當然,這很有道理,謝謝你的解釋! – kloffy 2010-04-09 23:47:53

回答

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); 
} 

注意的是,在類聲明的朋友比較例程是不一樣的聲明一個成員函數比較常規,這是爲什麼這些可能工作,而你的原始代碼可能不會。

+0

確實如此,謝謝!我有一種感覺,答案會非常簡單。 – kloffy 2010-04-09 23:39:45