2011-08-18 3 views
1

C++ 컴파일러는 이러한 함수 중 어떤 것이 호출되는지 어떻게 결정합니까?

인터페이스

template<class T> 
    void FooClass<T>::foo(boost::function<double (int)> f) 
{...} 

펑터를 사용하여 f를 구현하고 싶습니다.

class MyFun { 
    public: double operator()(int a) {do something...;} 
} 

그러나 인터페이스

에 정의 된 다른 함수가 있습니다.
template<class T> 
    template <class FunPtr> 
    void FooClass<T>::foo(const FunPtr& f) 
{...} 

FooClass 객체가 호출되면

MyFun f; 
FooClass<double> fooclass; 
fooclass.foo(f); 

두 번째 정의를 사용합니다. 첫 번째 정의를 호출하고 싶습니다. 어떻게 든 변경할 수 있습니까?

답변

6

컴파일러 'preferres' 두 번째 정의 때문에 대한 정확한 경기에서 템플릿 버전 결과 boost::function 매개 변수 이고 암시 적 변환이 필요합니다. 암시 적 변환은 직접 오버로드 해결 후 으로 간주됩니다. (난 그냥 명확성을 위해 별도로하고있어이 같은 줄에서이 작업을 수행 할 수 있습니다) 당신은 단지 boost::function 객체를 구성하여 당신이 원하는 것을 얻을 수 있고, 함수에 전달 다음는 :

boost::function<double (int)> bMyFun(myFunInstance); 
fooClassInstance.foo(bMyFun); 
2

당신은 명시 적으로 최초의 과부하가 선호됩니다 있도록 boost::function 객체를 생성 할 수 있습니까? 과부하가 선택되면 템플리트 화되지 않은 유형이 템플리트 화 된 유형보다 더 적합하지만 템플리트 형식 (FunPtr = MyFun)이 implictit 변환 (MyFun -> boost::function<double(int)>)보다 더 일치하므로 두 번째 오버로드가 원래 케이스.

(덕분에 내 원래의 제형에 눈부신 오류를 지적 @ 데이비드합니다!)

+0

답변 해 주셔서 감사합니다. 나는이 개념에 익숙하지 않은데, 지금은이 구체적인 예에서 어떻게 작동하는지 궁금합니다. – Hans

+0

* 잠재 암시 적 변환 체인은 과부하가 선택 될 때까지 고려되지 않습니다. * ??? 그것들은 고려되며, 이것이 최고의 과부하가 발견되는 방법입니다. 문제는 템플릿 버전이 변환이 필요한 것보다 더 적합하지만 과부하 해결은 두 가지 모두를 고려한 다음 템플릿을 결정할 것이라는 점입니다. –

+0

@David : 템플릿이 더 적합합니다. 왜냐하면 변환이 먼저 고려되면 함수가 boost :: function으로 변환 될 수 있다고 생각 될 것이고 첫 번째 오버로드가 더 나은 일치 일 것입니다. 그렇지 않습니까? –