当Lambda作为参数传递时,推断模板参数

7

我正在尝试编写函数func,以便编译器可以推断模板参数。当我传递std::function时,它可以工作,但是无法处理lambda表达式:

template<typename TResult>
TResult func(std::function<TResult()> f)
{
    return TResult();
}

int main()
{
                                // Visual Studio 2013
    int result = func([]() {    // error: 'TResult func(std::function<TResult(void)>)' : could not deduce template argument for 'std::function<TResult(void)>' from 'main::<lambda_d9d7854806072a2cb711f56185602ccb>'
        return 100;
    });

    std::function<int()> testFunc = []() {
        return 100;
    };
    int result2 = func(testFunc); // this works

    return 0;
}

是否有可能推断出lambda的模板参数,以便使此行代码编译通过?我想写成func([](){ return 100; });而不是func<int>([](){ return 100; });

4个回答

8
我有点迟到了 :) 这里有一个解决方案,不需要使用std::function
template<typename Class, typename R, typename... Args>
R resultType(R (Class::*)(Args...) const)
{
    return R();
}

template<typename Class, typename R, typename... Args>
R resultType(R (Class::*)(Args...))
{
    return R();
}

template<typename Functor>
auto func(Functor f) -> decltype(resultType(&Functor::operator()))
{
    return resultType(&Functor::operator());
}

非常好的解决方案!但是你不应该像const一样重载noexceptresultType()吗? - Mikhail Vasilyev

4

我无法立即看出如何做到这一点,但您可以通过间接方式实现:

template <typename TResult>
TResult func(std::function<TResult()> f) {
    return TResult();
}

template <typename Fun>
auto func(Fun f) -> decltype(f()) {
    return func(std::function<decltype(f())>(f));
}

2

至少按照我的理解,我相信你可以这样做:

template <class F>
auto foo(F &&f) -> decltype(f()) {
    typedef decltype(f()) ret_type;
    return ret_type();
}

如果您不想使用typedef,也可以这样做:

template <class F>
auto foo(F &&f) -> decltype(f()) {
    return decltype(f())();
}

完整的程序,比较使用和结果:

#include <functional>
#include <iostream>

template <class F>
auto foo(F &&f) -> decltype(f()) {
    return decltype(f())();
}

template<typename TResult>
TResult func(std::function<TResult()> f) {
    return TResult();
}

int main() {
   std::cout << foo([]() { return 100; })<<"\n";

    std::function<int()> testFunc=[]() { return 100; };
    std::cout << func(testFunc) <<"\n"; // this works

    return 0;
}

结果:

0
0

1

不,你不能在这里使用std::function,编译器无法推断其类型参数。

你应该只传递参数TFunction


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