2010-05-01 1 views
0

어떤 클래스의 "getter"메소드와도 작동 할 수있는 일반 알고리즘을 만드는 방법으로 boost :: lambda가 있습니다.부스트 람다 : 객체에 대한 메소드 호출

알고리즘은 속성의 중복 값을 검색하는 데 사용되며 모든 클래스의 속성에서 작동하도록하고 싶습니다. 두 인터페이스를 사용하여,

var duplicateIds = FindNonUniqueValues<Dummy>(d => d.GetId()); 
var duplicateNames = FindNonUniqueValues<Dummy>(d => d.GetName()); 

내가 일을 "모든 클래스"부분의를 얻을 수 있습니다 : 방법의

class Dummy 
{ 
    public String GetId() ... 
    public String GetName() ... 
} 

IEnumerable<String> FindNonUniqueValues<ClassT> 
    (Func<ClassT,String> propertyGetter) { ... } 

사용 예 : C#에서

, 나는 같은 것을 할 것 또는 템플릿 메소드를 사용하지만 "for any method"부분을 작동시키는 방법을 아직 찾지 못했습니다.

"d => d.GetId()"람다를 C++ (Boost 사용 여부에 관계없이)와 비슷한 방식으로 수행 할 수 있습니까?

알고리즘을 일반화하기위한 대안으로, C++ ian 솔루션을 사용해도 좋습니다.

VS2008에서 C++/CLI를 사용하므로 C++ 0x lambdas를 사용할 수 없습니다.

+1

는, A *는 "더 C++ 이안 솔루션"*은''기능의 스타일로 이동하는 것, 예를 들어, 참조 'unique()'/'unique_copy()'. –

+0

제 이해는 벡터가 이고 벡터에서 고유하지 않은 T를 찾고 싶을 때 unique()과 유사한 알고리즘이 작동하지만 고유하지 않은 T.method를 찾고있는 경우가 아닙니다.) – ckarras

+0

'unique()'와 같은 많은 알고리즘 호출은 기본 연산 대신 사용되는 술어를 전달할 수있는 두 번째 형식을 가지고 있습니다. 'unique (myVec.begin(), myVec.end(), myComparator())'. –

답변

6

가정, 난 당신이 boost::bind을 사용할 수 있습니다, 당신이 찾고있는 이해 :

FindNonUniqueValues<Dummy>(boost::bind(&Dummy::GetId, _1)); 

사실, 당신은 단지 당신에게 좀 더 일반성을 수 boost::mem_fn 또는 std::mem_fun하지만 boost::bind이 필요합니다. 이 경우

, 당신은 같은으로 FindNonUniqueValues을 정의하는 것입니다 : 여기

template <typename T> 
/* ? */ FindNonUniqueValues(boost::function<std::string (const T&)> getter) { ... } 

, 당신의 FindNonUniqueValues 개체의 목록을 얻는 방법 정말 모르겠어요 (또는 정확히 무엇을 반환 해야하는 것은 -이다 ?. 반복자 같은 IEnumerable), 그래서 당신이 그것을 채울 수 나중에 참조 할 수 있도록

+0

@gf, 물론, 왜 안 되니? (편집) –

+0

고마워, 나는 boost :: bind와 std :: mem_fun을 모두 시도했다. 두 솔루션 모두 작동하지만 std :: mem_fun이 내가 찾고있는 것과 더 잘 맞는 것을 발견했습니다. – ckarras

2

, 여기에 내가 함께 끝났다 솔루션입니다, 허용 대답에서 아이디어를 다음과 후 :

template < typename ObjectT, typename ValueT > std::vector <ObjectT> 
FindInstancesWithDuplicateValue(
    vector<ObjectT> allValues, mem_fun_ref_t<ValueT, ObjectT> getter) 
{ 
    // [...create a *sorted* list of ObjectT, ordered by ObjectT.getter()...] 
    // [...loop through the sorted list to find identical adjacent values...] 
     // call the mem_fun_ref_t: 
     ValueT value1 = getter(*iterPrev); 
     ValueT value2 = getter(*iter); 
     if (value1 == value2) // duplicates found 
    // ... 
} 

사용 예 : 당신을 위해 들어가는 경우

vector<Dummy> list; 
list.push_back(Dummy(1, "1-UniqueValue")); 
list.push_back(Dummy(2, "2-DuplicateValue")); 
list.push_back(Dummy(3, "2-DuplicateValue")); 
list.push_back(Dummy(4, "3-UniqueValue")); 

vector<Dummy> dummyWithduplicateNames = 
    FindInstancesWithDuplicateValue<Dummy,CString> 
    (list, mem_fun_ref(&Dummy::GetName)); 

// returns Dummy(2, "2-DuplicateValue") and Dummy(3, "2-DuplicateValue")