【问题标题】:Forwarding the Return Value of a Generic Callable Object转发通用可调用对象的返回值
【发布时间】:2017-02-20 06:41:19
【问题描述】:

下面的代码将参数包转发给一些用户定义的可调用对象(在本例中为函数指针)。 C++11 中有没有办法返回可调用的返回值?更具体地说,我希望能够推断 raise() 的返回类型,以便可以向其添加 return 语句。我意识到我可以只添加一个返回类型模板参数,但是我们应该不知道模板参数 Func 的返回类型吗?

size_t example(const std::string& str)
{
    return str.size();
}

template <class Func>
class signal
{
public:
    signal()
    {
    }

    ~signal()
    {
    }

    void attach(Func handler)
    {
        _handler = handler;
    }

    template <typename... T>
    void raise(T&&... args)
    {
        auto val = _handler(std::forward<T>(args)...);
       // How do I return this?
    }

private:
    Func _handler;
};

typedef size_t(*fcn)(const std::string&);

int main()
{
    signal<fcn> sig;
    sig.attach(&example);
    sig.raise("hello!");

    return 0;
}

【问题讨论】:

  • 你能使用 C++14 的特性吗?

标签: c++ c++11


【解决方案1】:

这就是 decltype 的用途。

template <typename... T>
auto raise(T&&... args) ->
  decltype(std::declval<Func&>()(std::forward<T>(args)...))
{
    return _handler(std::forward<T>(args)...);
}

decltype(expr) 给出expr 的类型。请注意,您需要在其中 argsFunc 可能是具有多个具有不同返回类型的重载 operator() 函数的函子对象,您需要参数类型来确定使用哪个重载。

【讨论】:

  • 在 C++14 中,您可以使用 -&gt; decltype(auto)... 或者如果您不关心引用性(即,您可以使用 copy ),那么你可以写-&gt; auto .
  • @Nawaz auto raise(...)-&gt; auto { 会不必要地冗长。 auto raise(...) { 可以。
  • @anderas:当然。我只是想保持我的评论简洁,因为这是一个小细节。
  • @Nawaz 注意:当Func 不能用给定的参数调用时,它的行为会有所不同。它变得无法通过 SFINAE 检测到,因为失败会在替换之外发生。
  • @hvd:是的,就是an important semantical difference。感谢您向我指出这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-28
  • 2018-04-03
相关资源
最近更新 更多