C++ 如何在类/函数模板中传递无效参数

C++ 如何在类/函数模板中传递无效参数,c++,class,templates,membership,void,C++,Class,Templates,Membership,Void,嘿,我正在尝试创建一个按钮模板类,它是用按下按钮时接收的按钮(例如鼠标位置)和指向应该调用的函数的指针构造的 但是,按钮通常返回void并且不带参数(您按下按钮就会发生一些事情:它们不带任何参数,它们被按下然后就做了一些事情。)那么既然显然不能将void作为参数类型,我该如何生成类成员函数呢? 如果有用的话,以下是来源: template<typename Return = void, typename Arg1 = void, typename Arg2 = 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; };
};
模板
类按钮
{
私人:
boost::函数;
//Return(*Function)(Arg1,Arg2);//这不起作用,所以我尝试了boost::Function
公众:
无效激活(Arg1,Arg2){函数(Arg1,Arg2);};
void SetFunction(返回(*函数)(Arg1、Arg2)){
这->函数=函数;};
//建设者
按钮(){Function=0;};
按钮(返回(*函数)(Arg1,Arg2)){
此->函数=&Function;};
};

如果我按照您的要求进行操作,您是否希望让用户可以为参数设置0-2个参数


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

您可以指定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();
    }
};
我希望这有助于澄清问题!:)


注意:
nullptr
是一个C++0x关键字,如果您的编译器没有实现它,请使用
#定义nullptr 0

如何使用模板?您所说的按钮经常返回空值且不带参数是什么意思?你指的是什么按钮?@Jaime:你按下按钮就会发生一些事情:它们不接受任何参数,它们被按下,然后就开始做一些事情。按钮是生成事件(即单击)的图形元素,你可以“钩住”函数来响应这些事件,这就是按钮“做”的方式。。ui框架定义了响应这些事件(参数类型和返回类型)时应该实现的签名,那么您希望如何使用模板?它的目的是什么?也许我们可以提出一些关于如何进行的建议许多编译器还没有实现可变模板,此外,模板专业化提供了一种更简洁、更直观的方法来解决OPs问题。你是否建议一个有5个月经验的程序员现在就学习Ox?最近有很多人都在建议……只要你愿意,就可以开始学习C++0x标准。然而,许多C++0x标准都是为了使高级编程概念更易于实现而设计的,因此,只有当您有更多的经验时,您才可能发现它们的用途。:)对我不知道你可以用不同的模板验证一个类!但有一个问题:如果我将其他成员数据/函数放在基类模板中,其他重载是否也会自动包含这些数据/函数?或者我必须复制每个模板重载的所有内容,而不仅仅是依赖于模板是什么的函数吗?不幸的是,您需要重新声明成员函数/变量,尽管这取决于您的专门化方式,只需复制和粘贴一些更改即可。
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";
}