简体   繁体   English

具有std :: function的C ++ 11类型推导

[英]C++11 Type Deduction With std::function

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++. 即使阅读了许多在线资源和其他问题,包括从带有std :: function的带lambda的返回类型和自变量类型的自动推论以及匿名lambda函数的 模板参数类型推导 ,我仍在努力用c ++清楚地表达以下内容。 I would like to avoid duplicate template arguments, which seem unnecessary. 我想避免重复的模板参数,这似乎是不必要的。

For example, container 'H' of generic type 'A' has a generic method 'M' for generic type 'B'. 例如,通用类型“ A”的容器“ H”具有通用类型“ B”的通用方法“ M”。 This expresses my intent for 'H' and method 'M': 这表达了我对“ H”和方法“ 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); }
};

My issue is calling 'M' requires duplicate template arguments for the function call and return container. 我的问题是调用“ M”需要为函数调用和返回容器使用重复的模板参数。 For type 'float', this isn't too bad, but with other symbols this gets unmanageable very quickly. 对于'float'类型,这还不错,但是对于其他符号,这很快就变得难以处理。

// 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); });

From this question , I tried a new definition of 'H' with a generic functor type 'F' instead of a generic result type: 这个问题开始 ,我尝试使用通用函子类型“ F”而不是通用结果类型对“ H”进行新定义:

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; });

But I find 'H2' almost offensive, there has to be a better way. 但是我发现“ H2”几乎令人反感,必须有更好的方法。

How can either the generic return type of a functor be restricted more cleanly or std::function be made to work with type inference? 函子的泛型返回类型如何被更清晰地限制,或者std :: function如何与类型推断一起使用? 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. 但随后您将必须传递一些虚拟值,这(不是我想要的)。


Here is the example, which can not convert lambda into std::function, because template parameter deduction fails : 这是示例,由于模板参数推导失败,无法将lambda转换为std :: function:

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM