2009-11-19 13 views
7

누군가가 이미이 질문을했지만 스레드가 원래 질문에 답변하지 못하게되었습니다.템플릿이있는 연산자() 오버로드 C++

template<size_t i, class f_type> 
void call_with_i(f_type f); 

functor_type 중 하나입니다 :

이이 있다고 가정

가) 다음과 같은 서명이있는 방법으로 구조체 :

template<size_t i> operator()() const; 

또는, B) 다음과 같은 함수 :

template<size_t i> foo(); 

나는 "call_with_i < 42> (푸)" "foo는 < 42>()"에 해당되고 싶어요,하지만 난 그렇게 할 수있는 권리 구문을 알아낼 수 없습니다. 나는 단지 (a) 하지만 (a) + (b)는 훌륭한 이 될 해결책으로 가득 차있다. 당신이 명시 적 템플릿 인수 연산자()를 호출하려면 어떻게해야

f<i>(); // doesn't work 
f()<i>; // doesn't work 
f.operator<i>(); // doesn't work 
f.operator()<i>; // doesn't work 
f.operator()<i>(); // works on msvc, but doesn't work on gcc. 

: 나는 이미 이러한 구문을 시도했습니다? 동일한 문법이 템플리트 화 된 자유 함수를 호출하는 방식으로 호출 할 수 있습니까?

p.s. 내가 이것을 위해 무엇을 사용하고 있는지 궁금하다면, repeat_to 함수를 작성했기 때문에 repeat_to < 10> (f)는 f (0), f (1) ... f (10)을 호출합니다. 나는 여러 부스트 :: 융합 벡터를 반복하여 인덱스로 병렬로 이걸 사용하고있다. 예, 반복자를 사용할 수도 있고, 명명 된 멤버 함수를 사용할 수도 있지만 여전히 대답을 알고 싶습니다.

편집 참고 사항 : 템플릿으로 처리 된 자유 함수를 arg로 전달하는 것은 의미가 없기 때문에 나는 물건을 뜯어 냈습니다.

+0

당신이 할 수 없기 때문에 대답하지 못했습니다. – GManNickG

답변

13

구성원 템플릿의 의미는 f_type 유형에 따라 다르므로 종속 템플릿입니다. 해결 방법으로

template<size_t i, class f_type> 
void call_with_i(f_type f) { 
    f.template operator()<i>(); 
    // f.template foo<i>(); 
} 

을, 당신 : 그것은 당신이 비슷한, 당신이 따라 자격을 갖춘 이름 전에 typename을 넣어하는 방법에 (이하 "보다 작음"토큰의 사용을 명확하게하는)의 이름 앞에 "템플릿"을 넣어한다는 뜻 도우미 유형 사용할 수 있습니다 : 이제 다음과 같이

template<size_t N> struct size_t_ { }; // or boost::mpl::int_ 

template<size_t i, class f_type> 
void call_with_i(f_type f) { 
    f(size_t_<i>()); 
} 

을, 당신은 당신의 operator()를 정의 할 수 있습니다 :

template<size_t i> void operator()(size_t_<i>) const { 
    // i was deduced automatically by the function argument. 
} 

이 w를 들어, 템플릿 생성자에 대한 편리한 온다 너 f_type()<i>() 또는 뭔가 할 수 없어. 그들은 을 공경 할 수 있습니다.

+0

@Johannes : SFINAE를 사용하는 기능을 전문으로하지 않는 이유는 무엇입니까? –

+0

위대한 작품! 엄청나 다. 너는 내 메타 영웅이야. 아, 그리고 mpl :: int_를 사용하여 생각하는 것도 똑똑합니다. – Glenn

+0

@ laulaulabs.mp, 도움이되어 기쁩니다 :) –

0
#include <iostream> 

template<size_t i, class f_type> void call_with_i(f_type f); 

struct A { 

    template < size_t i > 
    void operator()() const { 
     /* no link err in demo */ 
    } 

    template < size_t i > 
    void foo() { 
     /* no link err in demo */ 
    } 
}; 

int main(int argc, char * const argv[]) { 
    A f; 

    enum { Constant = 42 }; 

    f.operator()<Constant>(); 
    f.foo<Constant>(); 

    return 0; 
} 

동일한 구문도 템플릿 무료 함수를 호출 할 것이라고 방식으로 호출 할 수있는 방법이 있습니까?

당신이 명확히 할 수 있습니까? (의사 코드 등)

+0

사실 템플릿 기반의 자유 함수에 대한 내 생각은 함수 템플릿을 인수로 전달할 수 없으므로 난센스입니다. – Glenn

1

당신의 경우에는 boost :: function을 functor 유형으로 사용합니다. 그런 다음 동일한 인터페이스를 유지하면서 함수 객체와 함수 포인터를 모두 전달할 수 있습니다.