2009-11-27 2 views
1

템플릿 클래스를 사용하여 변환 할 수없는 이유를 찾는 데 어려움을 겪고 있습니다.템플릿을 사용하여 std :: transform을 사용하는 방법

여기에 단순화 된 템플릿 클래스의 버전입니다 :

template<typename T> 
class base 
{ 
public : 
    base() : all_() {} 
    ~base() {} 
public: 
    bool add(T t) 
    { 
    typename vector<T>::iterator itr 
     = lower_bound(all_.begin(), all_.end(), t); 
    if (itr == all_.end() || *itr != t) 
     { 
     all_.push_back(t); 
     cout << "ok" << endl; 
     return true; 
     } 
    cout << "failed" << endl; 
    return false; 
    } 
    static bool addTo(base<T> *c, T t) 
    { 
    return c->add(t); 
    } 
private : 
    vector<T> all_; 
}; 

그리고 이것은 내가 추가 멤버 함수의 모든 부울 출력을 캡처 변환을 사용하려고 시도하고있는 곳입니다 :

main() 
{ 
    base<int> test; 
    vector<bool> results; 
    vector<int> toAdd; 
    toAdd.push_back(10); 
    toAdd.push_back(11); 
    toAdd.push_back(10); 
    transform(toAdd.begin(), toAdd.end(), 
      back_inserter(results), 
      bind1st((bool(*)(base<int>*,int))base<int>::addTo, &test)); 
} 

base :: add 또는 base :: addTo를 사용하여 toAdd 컨테이너의 각 멤버를 삽입하고 벡터 결과에 부울 결과를 캡처하는 것입니다.

+2

질문 무엇입니까? "왜이 코드가 컴파일되지 않는가"라면 C++의 함수 정의는 리턴 타입을 가져야하고'main'은 리턴 타입이'int'입니다 ;-) –

+0

무엇을 달성하려고하는지 설명 할 수 있습니까? 변환? – Naveen

+0

수정 - 컴파일 할 수 없습니다. 모든 타입의 main을주는 것은 모든 컴파일러의 전제 조건이 아닙니다. – youngthing

답변

6

시도 :

문제는 템플릿이 아니며, bind1st가 작동하려면 별도의 지원이 필요합니다 (http://www.sgi.com/tech/stl/AdaptableBinaryFunction.html 참조). AFAIK는 일반 구형 함수 포인터에서 작동 할 수 없습니다.

boost::bind이 작업을 수행하려면 더 많은 작업을 수행 할 수 있습니다.이 경우에는 필요하지 않습니다. mem_fun은 비 정적 멤버 함수를 적용 가능한 이진 함수로 바꿉니다. 따라서 addTo도 필요하지 않지만 유사한 상황에서 정적 멤버 함수를 사용해야하는 경우 ptr_fun이 있습니다.

typedef base<T>* first_argument_type; 
typedef T second_argument_type; 
typedef bool result_type; 

bool operator() (base<T> *c, T t) const { 
    return c->add(t); 
} 

및 변경에 변환 :

+0

그거야. 팁, 특히 현자주의에 감사드립니다. – youngthing

+0

그리고 * 이유 * 그것이 작동하면'bind1st'는 일반 함수 포인터를 받아들이지 않습니다. 펑터 객체가 필요합니다. 'mem_fun'과'ptr_fun' 함수는 함수 포인터를 바인더와 함께 사용하기에 적합한 펑터로 변환합니다. –

+0

@RobKennedy : 감사합니다. 그 말이 많은 의미가 있으며, Josutis STL 책에서 아직 선택하지 않은 것입니다. 할 수 있다면 나는 당신과 하나의 레크를 줄 것이다! – youngthing

0

은 당신의 기본 클래스에 다음을 추가

transform(toAdd.begin(), toAdd.end(), 
      back_inserter(results), bind1st(base<int>(), &test)); 
+0

내 클래스 (기본)가 컨테이너 만 저장하려고한다면 괜찮을 것입니다. 단순히 항목을 추가하기 위해 operator()를 쓰는 것에 신경 쓰지 않을 것입니다. 내 적절한 코드는 훨씬 더 많은 책임을 가지고 있습니다. – youngthing

+0

당신은 작은 구조체를 만들 수있는 '기본'클래스에 add를 배치 할 필요가 없습니다. 제가 제공 한 코드를 포함하고있는 'Adder'라고 말하십시오. 그런 다음베이스 을 'Adder'로 바꿉니다. 하지만 mem_fun 어댑터도 잘 작동합니다;) –

관련 문제