2011-07-27 4 views
2

안녕하세요 저는 버튼을 누를 때 (마우스 위치와 같이) 수신 대기열에 대한 포인터를 생성하는 Button 템플릿 클래스를 만들려고합니다. 호출되어야하는 함수.클래스/함수 템플릿에서 무효 인수를 전달하는 방법

그러나 단추는 종종 void를 반환하고 아무런 인자도 가지지 않습니다 (누르는 버튼이 발생합니다. 아무런 인자도 가지지 않고 눌렀다가 무언가를합니다.) 어떻게 클래스 멤버를 생성합니까? 함수는 분명히 이후 void을 인수 유형으로 가질 수 없습니까?

는 여기가 도움이 경우 소스입니다 :

template<typename Return = void, typename Arg1 = void, typename Arg2 = void> 
class Button 
{ 
private: 
    boost::function<Return (Arg1, Arg2)> Function; 
    //Return (*Function)(Arg1, Arg2);    // this didn't work so i tried boost::function 

public: 
    void Activate(Arg1, Arg2){ Function(Arg1, Arg2) ;}; 

    void SetFunction(Return (*Function)(Arg1, Arg2)){ 
     this->Function= Function;}; 

    //constructors 
    Button(){ Function= 0;}; 

    Button(Return (*Function)(Arg1, Arg2)){ 
     this->Function = &Function; }; 
}; 
+0

를 사용하는 C++ 0X 키워드인가? 버튼이 의미하는 바는 종종 무효로 돌아가고 args를받지 않는다는 것입니다. 어떤 버튼을 언급하고 있습니까? – Jaime

+0

@Jaime : 당신이 누르는 것과 어떤 일이 일어나는 버튼 : 그들은 아무런 논쟁도하지 않고, 눌렀다가 무언가를합니다. – Griffin

+2

버튼은 이벤트를 생성하는 그래픽 요소입니다 (예 : 클릭). 해당 이벤트에 응답하는 함수를 '훅 (hook)'하고 단추가 '하는 일'을 나타내는 함수입니다. UI 프레임 워크는 해당 이벤트에 응답하도록 구현해야하는 서명을 정의합니다 (args와 return 타입의 타입) 어떻게 당신은 당신의 템플릿을 사용하고 싶습니까? 그것의 목적은 무엇이며 어쩌면 우리는 그것에 대해 갈 방법에 대한 제안을 내놓을 수 있습니다. – Jaime

답변

4

당신은, 예를 들어, 당신은 템플릿 클래스의 다음과 같은 변화를 사용할 수, button을 void 형식의 템플릿 사양을 지정할 수 있습니다

template <typename rtnVal, typename Val1, typename Val2> 
class Button { 
private: 
    rtnVal(*Function)(Val1 val1, Val2 val2); 

public: 
    Button() : Function(nullptr) {} 

    void SetFunction(rtnVal(*func)(Val1, Val2)) { 
     Function = func; 
    } 

    rtnVal RunFunction(Val1 val1, Val2 val2) { return Function(val1, val2); } 
}; 

// Special void type, accepting arguments overload: 
template < typename Val1, typename Val2 > 
class Button< void, Val1, Val2 > { 
private: 
    void(*Function)(Val1 val1, Val2 val2); 

public: 
    Button() : Function(nullptr) {} 

    void SetFunction(void(*func)(Val1, Val2)) { 
     Function = func; 
    } 

    void RunFunction(Val1 val1, Val2 val2) { return Function(val1, val2); } 

}; 

// Pure void type: 
template<> 
class Button<void, void, void> { 
private: 
    void(*Function)(void); 

public: 
    Button() : Function(nullptr) {} 

    void SetFunction(void(*func)()) { 
     Function = func; 
    } 

    void RunFunction() { 
     return Function(); 
    } 
}; 

를이 다음를 들어, 초기화 인수로 공백을 사용할 수 있습니다 예, 다음은 현재 유효한 것입니다 무효 기능 Print()을 제공 :

void Print() 
{ 
    std::cout << "Function has been called" << std::endl; 
} 

int main() 
{ 
    Button< void, void, void > btn; 

    btn.SetFunction(Print); 

    btn.RunFunction(); 

    std::cout << "Finished"; 
} 

나는이 일을 취소 도움이되기를 바랍니다! :)

참고 : nullptr 당신의 컴파일러가 구현되지 않은 경우 당신이 당신의 템플릿을 사용하려면 어떻게 #define nullptr 0

+0

예. 저는 다른 템플릿으로 수업을 배울 수 있다는 것을 몰랐습니다! ** 하나의 질문 : ** 다른 멤버 데이터/함수를 기본 클래스 템플릿 안에 넣으면 다른 오버로드에도 자동으로 포함됩니다. 아니면 각 템플릿 과부하 모두를 복사해야하고, 템플릿이 무엇인지에 의존하는 함수가 아닌가? – Griffin

+0

불행히도 멤버 함수/변수를 다시 선언해야합니다.하지만 전문적 방법에 따라 몇 가지 변경 사항 만 복사하여 붙여 넣기 만하면됩니다. –

0

난 당신이 그렇게 사용자가 PARAMS에 0-2 인수를 가질 수 있습니다 갖고 싶어 따르는 경우에?

C++ 0x를 사용하고자한다면 variadic 템플릿을 사용할 수 있습니다. 이렇게하면 필요한만큼 많은 arg를 사용할 수 있습니다.

+0

많은 컴파일러는 가변성 템플릿을 아직 구현하지 않았습니다. 게다가 템플릿 전문화는 OP 문제를 더 깔끔하고보다 직관적으로 해결할 수있는 방법을 제공합니다. –

+0

약 5 개월의 경험을 가진 프로그래머에게 지금 Ox을 제안 해 주시겠습니까? 많은 사람들이 최근에 그것을 제안하고 있습니다 ... – Griffin

+0

당신이 원할 때마다 C++ 0x 표준을 배울 수 있습니다. 그러나 많은 C++ 0x 표준은 고급 프로그래밍 개념을보다 쉽게 ​​구현할 수 있도록 설계되었으므로 좀 더 많은 경험이있을 때만 이러한 기능을 사용할 수 있습니다. :) –

관련 문제