2010-04-30 160 views
1

我想通過lambda :: bind調用成員。不幸的是,我有兩個具有相同名稱但返回類型不同的成員。 有沒有辦法來幫助lambda :: bind推斷成員函數調用的正確返回類型? (結合正常工作與明確的返回類型扣)boost lambda :: bind返回類型選擇

#include <vector> 
#include <iostream> 
#include <algorithm> 
#include <boost/bind.hpp> 
#include <boost/lambda/lambda.hpp> 
#include <boost/lambda/bind.hpp> 

using namespace std; 
using namespace boost; 

struct A 
{ 
    A (const string & name) : m_name(name) {} 

    string &  name()   { return m_name; } 
    const string & name() const { return m_name; } 

    string m_name; 
}; 

vector<A> av; 

int main() 
{ 
    av.push_back (A ("some name")); 

    // compiles fine 
    find_if(av.begin(), av.end(), bind<const string &>(&A::name, _1) == "some name"); 

    // error: call of overloaded 'bind(<unresolved overloaded function type>, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >&)' is ambiguous 
    find_if(av.begin(), av.end(), lambda::bind(&A::name, lambda::_1) == "some name"); 

    return 0; 
} 

回答

1

不同的退貨類型是紅鯡魚。問題在於方法的const重載(即無論相對返回類型是什麼,你都會遇到同樣的問題)。這是問題記錄herehere,並使用返回類型指定的形式是not the recommended solution(大多數情況下,除某些版本的MSVC以外)。

問題是,重載成員函數(常量重載或參數重載)的地址是不明確的,所以需要一些額外的信息。

解決方案是轉換函數指針,它可以讓編譯器確切地知道你想要的是哪個重載函數。我找到的最簡潔的方法是typedef函數指針類型,否則行會得到有點討厭。這裏是你的代碼的例子(編譯乾淨GCC 4.3.4):

#include <vector> 
#include <iostream> 
#include <algorithm> 
#include <boost/bind.hpp> 
#include <boost/lambda/lambda.hpp> 
#include <boost/lambda/bind.hpp> 

using namespace std; 
using namespace boost; 

struct A 
{ 
    A (const string & name) : m_name(name) {} 

    string &  name()   { return m_name; } 
    const string & name() const { return m_name; } 

    string m_name; 
}; 

vector<A> av; 

//function pointer for non-const version 
typedef string& (A::*NameFuncType)(void); 

//function pointer for const version 
typedef const string& (A::*NameConstFuncType)(void) const; 

int main() 
{ 
    av.push_back (A ("some name")); 

    //'correct' way to call const version w/ boost::bind 
    find_if(av.begin(), av.end(), 
    bind(static_cast<NameConstFuncType>(&A::name), _1) == "some name" 
); 

    //call for non-const version w/ boost::lambda::bind 
    find_if(av.begin(), av.end(), 
    lambda::bind(static_cast<NameFuncType>(&A::name), lambda::_1) == "some name" 
); 

    return 0; 
} 
1

有關文檔

「由bind表達式創建的lambda仿函數的返回類型可以被給定爲一個顯式指定的模板參數,如在下面的例子:

綁定(目標功能,綁定參數列表)」

所以只要你有增強做同樣的事情:綁定。

find_if(av.begin(), av.end(), lambda::bind<const string &>(&A::name, lambda::_1) == "some name"); 

P.S.未經測試

+0

您剛纔指出了真正的問題:) 有一種方法來覆蓋拉姆達的返回類型::提升,但它僅適用爲lambda表達式不爲綁定。參見:lambda :: ret (e)。不幸的是,在目前的情況下,它不適用... – psaghelyi 2010-04-30 21:27:50