【问题标题】:How to pass void arguments in a class/function templates如何在类/函数模板中传递 void 参数
【发布时间】:2011-10-13 20:54:24
【问题描述】:

嘿,我正在尝试制作一个 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; };
};

【问题讨论】:

  • 您想如何使用您的模板?按钮经常返回 void 并且不带参数是什么意思?你指的是什么按钮?
  • @Jaime:您按下按钮并发生某些事情:它们不接受任何参数,它们被按下然后只是做某事。
  • 按钮是生成事件(即点击)的图形元素,你“挂钩”函数来响应这些事件,这就是按钮如何“做”它的事情.. ui 框架定义了你的签名应该实现以响应这些事件(参数类型和返回类型)所以你想如何使用你的模板?这样做的目的是什么,也许我们可以提出一些关于如何去做的建议

标签: c++ class templates membership void


【解决方案1】:

您可以指定 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 作为参数,例如,给定一个 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

【讨论】:

  • 是的。我不知道你可以用不同的模板覆盖一个类! 一个问题: 如果我将其他成员数据/函数放入基类模板中,其他重载是否也会自动包含这些?还是我必须复制每个模板重载的所有内容,而不仅仅是依赖于模板的函数?
  • 不幸的是,您需要重新声明成员函数/变量,不过,这取决于您的专业化程度,只需复制和粘贴一些更改即可。
【解决方案2】:

如果我关注你想要它,以便用户可以有 0-2 个参数作为参数?

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

【讨论】:

  • 许多编译器还没有实现可变参数模板,此外,模板专业化提供了一种更简洁、更直观的方式来解决 OPs 问题。
  • 你会建议现在有大约 5 个月经验的程序员学习 Ox 吗?最近很多人都在建议...
  • 您可以随时开始学习 C++0x 标准。但是,许多 C++0x 标准旨在使高级编程概念更易于实现,因此您很可能只有在有更多经验时才能使用它们。 :)
猜你喜欢
  • 2016-06-01
  • 2021-09-26
  • 1970-01-01
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多