4

좋아요, 먼저 샘플 코드를 입력하십시오. 이 컴파일되지 않지만이, 그것이 내가 할 노력하고있어 것입니다 무엇을 전달하려고 시도한 것이다 :특수 버전을 사용하여 여러 개의 상속 된 템플릿 함수 재정의

#include <iostream> 

template <class T> 
class Base 
{ 
public: 
    virtual void my_callback() = 0; 
}; 

class Derived1 
    : public Base<int> 
    , public Base<float> 
{ 
public: 
    void my_callback<int>() 
    { 
     cout << "Int callback for Derived1.\n"; 
    } 
    void my_callback<float>() 
    { 
     cout << "Float callback for Derived\n"; 
    } 
}; 

class Derived2 
    : public Base<int> 
    , public Base<float> 
{ 

public: 
    void my_callback<int>() 
    { 
     cout << "Int callback for Derived2.\n"; 
    } 
    void my_callback<float>() 
    { 
     cout << "Float callback for Derived2\n"; 
    } 

}; 

int main() 
{ 
    { 
     Derived1 d; 
     Base<int> * i_p = d; 
     Base<float> * i_f = d; 

     i_p->my_callback(); 
     i_f->my_callback(); 
    } 
    { 
     Derived2 d; 
     Base<int> * i_p = d; 
     Base<float> * i_f = d; 

     i_p->my_callback(); 
     i_f->my_callback(); 
    } 

    //Desired output: 
    // Int callback for Derived1. 
    // Float callback for Derived1 
    // Int callback for Derived2. 
    // Float callback for Derived2 
    system("Pause"); 
} 

그래서를, 난 할 노력하고있어 상속 래퍼 클래스의 종류를 확인하는 것입니다 이로부터 파생 클래스를 다양한 콜백리스트에 자동으로 연결합니다. 파생 클래스의 특정 인스턴스를 목록에 연결해야하며 "사용자"가 파생 클래스를 만드는 과정에서 콜백 함수를 만들도록하고 싶습니다.

다른 구문을 사용해야 할 수도 있지만 작동해야하는 것처럼 보입니다. 작동하지 않는 경우 제안 사항이 있습니까?

답변

-1

예, 당신이이 일을 할 수

#include <iostream> 
using namespace std; 

template <class T> 
class Base 
{ 
public: 
    virtual void my_callback() = 0; 
}; 

class Derived1 : public Base<int>, public Base<float> 
{ 
public: 
    void Base<int>::my_callback() { 
    cout << "Int callback for Derived1.\n"; 
    } 
    void Base<float>::my_callback() { 
    cout << "Float callback for Derived\n"; 
    } 
}; 

class Derived2 : public Base<int>, public Base<float> 
{ 
public: 
    void Base<int>::my_callback() { 
    cout << "Int callback for Derived2.\n"; 
    } 
    void Base<float>::my_callback() { 
    cout << "Float callback for Derived2\n"; 
    } 
}; 

int main() 
{ 
    { 
    Derived1 d; 
    Base<int> * i_p = &d; 
    Base<float> * i_f = &d; 
    i_p->my_callback(); 
    i_f->my_callback(); 
    } 
    { 
    Derived2 d; 
    Base<int> * i_p = &d; 
    Base<float> * i_f = &d; 
    i_p->my_callback(); 
    i_f->my_callback(); 
    } 
} 

출력 : 당신이 원하는 무엇

Int callback for Derived1. 
Float callback for Derived 
Int callback for Derived2. 
Float callback for Derived2 
+1

컴파일되지 않습니다 (gcc). Derived :: my_callback의 선언은 그렇게 작동하지 않습니다. – Frunsi

+0

이 작품은 나를 위해; 참고로 Visual Studio 2008을 사용하고 있는데 표준이 아닌 몇 가지 기능이 있습니다. 감사! – Narfanator

+0

네, 이는 명시 적 인터페이스 구현을 지원하는 부작용입니다. MSVC를 계속 사용할 수만 있다면 괜찮을 것입니다. –

2

이 가능 없습니다.

나도 몰라하지만이 정말 도움이된다면 당신은 템플릿 전문화를 추가 할 수 있습니다

template <class T> 
class Base { 
public: 
    virtual void my_callback() = 0; 
}; 

template <> 
class Base<int> { 
public: 
    virtual void my_callback() { 
    cout << "Base<int>::my_callback()\n"; 
    } 
}; 

template <> 
class Base<float> { 
public: 
    virtual void my_callback() { 
    cout << "Base<float>::my_callback()\n"; 
    } 
}; 

class Derived1 : public Base<int>, public Base<float> { 
public: 
    // NOTE: no my_callback() implementation here 
}; 

class Derived2 : public Base<int>, public Base<float> { 
public: 
    virtual void my_callback() { 
    cout << "Derived2::my_callback()\n"; 
    } 
}; 


int main() 
{ 
    { 
    Derived1 d; 
    Base<int> * i_p = &d; 
    Base<float> * i_f = &d; 
    i_p->my_callback(); 
    i_f->my_callback(); 
    } 
    { 
    Derived2 d; 
    Base<int> * i_p = &d; 
    Base<float> * i_f = &d; 
    i_p->my_callback(); 
    i_f->my_callback(); 
    } 
} 

출력 :

Base<int>::my_callback() 
Base<float>::my_callback() 
Derived2::my_callback() 
Derived2::my_callback() 

내게 설명하려고하자 이유 :

Derived1 d; 
Base<int> * i_p = &d; 
Base<float> * i_f = &d; 

// will check the vtable, and will call 
// either Derived1::my_callback 
// OR Base<int>::my_callback 
i_p->my_callback(); 

// will check the vtable, and will call 
// either Derived1::my_callback 
// OR Base<float>::my_callback 
i_f->my_callback(); 

vtable에는 Derived1 클래스에 my_callback()의 ​​두 가지 버전이 있지만, t 밑단, 예를 들어 Derived2가 한 번에 모두 오버라이드 할 수 있습니다!

"my_callback1()"과 "my_callback2()"의 두 가지 메소드 만 제공하면됩니다.

-1

가상도템플릿이 머리에 알람을 발생시키지 않습니까? ;)

정적이거나 동적 인 쪽을 선택해야합니다.

+0

"템플릿과 연관된 가상성이 당신의 머리에 경보를 발생시키지 않습니까?" "왜 그러겠습니까? – curiousguy

0

템플릿 클래스 또는 템플릿이 아닌 템플릿을 사용하는 경우 this style 또는 this one의 도우미 클래스를 사용하여이 작업을 수행 할 수 있습니다.

(Microsoft 고유의 정규화 된 이름을 사용하지 않으려면이 솔루션 만 사용하는 것 같습니다.)