2011-07-27 45 views
2

嘿,我试图做一个Button模板类,它是用构造的,按钮会在按下时收到(例如鼠标位置)和一个指向应该调用的函数。如何在类/函数模板中传递void参数

但是按钮通常会返回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

你怎么想使用你的模板?你是什​​么意思的按钮往往返回无效,并没有参议员?你指的是哪些按钮? – Jaime

+0

@Jaime:你按下按钮,发生什么事情:他们不接受任何参数,他们被按下,然后只是做一些事情。 – Griffin

+2

按钮是生成事件(即点击)的图形元素,您'挂钩'功能以响应这些事件,以及按钮'如何'做它的事情。ui框架定义您应该实现以响应这些事件的签名(参数的类型和返回类型)所以你想如何使用你的模板?它的目的是什么,也许我们可以提出一些关于如何去做的建议。 – Jaime

回答

4

您可以指定void类型的模板规范,例如,你可以使用模板类的以下变化,button

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(); 
    } 
}; 

这就可以让你初始化和使用无效作为参数,对例如,给出一个void函数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是一个C++ 0x中的关键字,如果你的编译器没有实现它使用#define nullptr 0

+0

是的。我不知道你可以使用不同的模板来创建一个类。 **但有一个问题:**如果我要将其他成员数据/函数放入基类模板中,其他重载是否也会自动包含这些数据/函数?或者我将不得不复制每一个模板重载的所有东西,而不仅仅是依赖于模板的函数? – Griffin

+0

不幸的是,您需要重新声明成员函数/变量,但取决于您如何专门化,它只是复制和粘贴一些更改的问题。 –

0

,如果我跟着你想拥有它使用户可以有0-2 args作为PARAMS?

如果你愿意使用C++ 0x,那么你可以使用可变参数模板。这将允许您根据需要使用尽可能多或更少的参数。

+0

许多编译器还没有实现可变参数模板,此外,模板专门化为解决OP问题提供了一种更简洁更直观的方法。 –

+0

您是否建议现在向有程序员学习5个月左右的经验?很多人最近都在暗示它...... – Griffin

+0

只要你觉得你愿意,你可以开始学习C++ 0x标准。然而,许多C++ 0x标准旨在使高级编程概念更容易实现,所以当你有更多的经验时,你很可能只会使用它们。 :) –

相关问题