调用std::函数

3
我正在尝试编写一个类模板,其在构造函数参数中获取两个 std::function 并在构造和析构过程中以 RAII 的方式调用它们。
我缺少什么?
template <class T>
class HelloGoodbye{
public:
HelloGoodbye(std::function<T> const & f, std::function<T> const &g)
  :mf(f),mg(g)
{
  mf();
}


~HelloGoodBye()
{
  mg();
}

private:
std::function<T> mf;
std::function<T> mg;
};


class Printer
{
    public:
    void hello()
    {
        std::cout << "hello!" << std::endl;
    }
    void goodbye()
    {
        std::cout << "Goodbye!" << std::endl;   
    }
};

int main()
{
      Printer p;
      auto hi = std::bind(&Printer::hello, &p);
      auto bye = std::bind(&Printer::goodbye, &p);
      HelloGoodbye hgb(hi,bye);      
}

你不需要保存mf - John
2个回答

3

HelloGoodbye 是一个类模板,在使用时需要指定模板参数,例如:

HelloGoodbye<void()> hgb(hi,bye);   

现场演示

顺便说一下:我认为~HelloGoodBye()~HelloGoodbye()的错别字。


0

你可以像songyuanyao建议的那样显式指定hgb的模板类型,或者你可以创建一个make函数。

template <typename T>
HelloGoodbye<T> makeHG (std::function<T> const & hi,
                        std::function<T> const & bye)
 { return { hi, bye }; }

而且,使用 auto,您可以初始化 hgb 如下所示

auto hgb = makeHG(hi, bye);

不幸的是,std::bind 是一个具有未定义返回值的奇怪的东西,因此您无法将从 std::bind 返回的类型传递给 makeHG() 以获得 T 类型推断。

因此,如果您想使用 makeHG(),您可以使用 auto 定义 hibye,但您必须显式指定类型,如下所示:

  std::function<void()> hi = std::bind(&Printer::hello, &p);
  std::function<void()> bye = std::bind(&Printer::goodbye, &p);

所以,我想索尼原腰可能是更好的解决方案。


一旦他使用make函数构建一个模板类,他就不再需要重量级的std :: function了。他可以只对可调用类型进行模板化,并存储闭合的一个。 - John
考虑到 fg 必须是可调用的且不带参数,我们可以从 std::bind 创建函数签名;假设 std::is_bind_expression<T>::valuetruedecltype(std::declval<T>()()) 是有效类型,则提供给 std::function 的签名应为 typename T::result_type()像这样。然而,这可能有些脆弱,我不知道它是否是良好的实践。 - Justin Time - Reinstate Monica
@JustinTime - 谢谢,但是...我认为这个解决方案(而且我不认为它很脆弱)不太有趣;因为它只适用于这种特定的(没有参数)情况;我已经寻找了一个更通用的解决方案(相当于编写一个模板“make”函数来将std::bind()返回值转换为相应的std::function值并检测其类型),但没有成功。 - max66
@max66 哦,好的。很遗憾,我不知道如何从任何 std::bind 中获取一个独立的函数类型。可能有一些方法可以做到这一点,但我对 bind 不够熟悉,不知道具体是什么;我猜想它可能涉及某种模板魔法,通过消除来构建参数列表,但这只是一个猜测。 - Justin Time - Reinstate Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接