C ++ 11类型扣除使用std :: function [英] C++11 Type Deduction With std::function

查看:152
本文介绍了C ++ 11类型扣除使用std :: function的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使阅读了许多在线资源和其他问题,包括模板参数类型从std :: function中推导返回类型为lambda 参数类型自动扣除和匿名lambda函数,我很难在c ++中清楚地表达以下内容。

Even after reading many online resources and other questions, including template argument type deduction from std::function return type with lambda and Argument type auto deduction and anonymous lambda functions, I am struggling with clearly expressing the following in c++. I would like to avoid duplicate template arguments, which seem unnecessary.

例如,泛型类型'A'的容器'H'有一个泛型方法'M'类型B。这表示我'H'和方法'M'的意图:

For example, container 'H' of generic type 'A' has a generic method 'M' for generic type 'B'. This expresses my intent for 'H' and method 'M':

template<typename A>
struct H
{
    explicit H(A x) : x(x) { }
    A x;

    template<typename B>
    H<B> M(std::function<H<B>(A)> g) { return g(x); }
};

我的问题是调用'M'需要重复的模板参数的函数调用和返回容器。对于类型float,这不是太糟糕了,但是与其他符号,这很快就难以管理。

My issue is calling 'M' requires duplicate template arguments for the function call and return container. For type 'float', this isn't too bad, but with other symbols this gets unmanageable very quickly.

// This works but requires the duplicate 'float'
H<int>(1).M<float>([](int x) { return H<float>(x + 3.14); });

// These would be preferred, but neither works
H<int>(1).M<float>([](int x) { return H(x + 3.14); });
H<int>(1).M([](int x) { return H<float>(x + 3.14); });

这个问题,我尝试了一个新的定义'H'与通用函子类型'F',而不是一般的结果类型: / p>

From this question, I tried a new definition of 'H' with a generic functor type 'F' instead of a generic result type:

template<typename A>
struct H2
{
    enum { IS_H2 = true };

    explicit H2(A x) : x(x) { }
    A x;

    template<typename F,
        class = typename std::enable_if<std::result_of<F(A)>::type::IS_H2>::type>
    auto M(F g) -> decltype(g(x)) { return g(x); }
};

它允许使用所需的语法:

which allows the desired syntax:

// This now is valid
H2<int>(1).M([](int x) { return H2<float>(x + 3.14); });

// And, as expected, this is not
H2<int>(1).M([](int x) { return x + 3.14; });

但我发现'H2'几乎是攻击性的,必须有更好的方法。

But I find 'H2' almost offensive, there has to be a better way.

如何使函数的泛型返回类型限制得更干净或者使用std :: function来处理类型推断?

How can either the generic return type of a functor be restricted more cleanly or std::function be made to work with type inference? Or am I attacking the problem from the wrong angle entirely?

推荐答案

这是函数模板的工作原理,没有办法解决这个问题。

That is how function template works, and there are no ways around.

如果在函数参数中有参数,则自动模板参数扣除完成,这里不是这样。例如,编译器可以推导出这个函数中的类型:

Automatic template parameter deduction is done if you have a parameter in the function parameter, which is here not the case. For example, the compiler can deduce type in this function :

template<typename B>
H<B> M(std::function<H<B>(A)> g, const B&) { return g(x); }

但是你必须传递一些虚拟值,这是

but then you would have to pass some dummy value, which is (I think) not what you want.

下面是示例,无法将lambda转换为std :: function,因为模板参数扣除失败:

Here is the example, which can not convert lambda into std::function, because template parameter deduction fails :

#include <functional>

template<typename A>
struct H
{
    explicit H(A x) : x(x) { }
    A x;

    template<typename B>
    H<B> M(std::function<H<B>(A)> g, const B&) { return g(x); }
};

int main()
{
    H<int> h(1);

    std::function<H<float>(int)> g( [](int x){ return H<float>(x + 3.14); } );
    const auto v = h.M( g, 5.5f );

    (void)v;
}

这篇关于C ++ 11类型扣除使用std :: function的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆