从参数的返回类型中推断类型

时间:2017-05-16 06:12:48

标签: c++ c++11 gcc c++14

据我所知,模板无法从分配中推断出类型,即

template <typename T>
T aFunction (int a) { /*...*/ }; // This obviously won't work

这很明显为什么。但是这个工作:

template <typename T>
T aFunction (T a, T b) { return a + b; }; // a-ok

'因为T将从参数中推断出来。我想从中推断一下:

template <typename T>
T aFunction (std::function<T(int)> a) { return a(3);};
                           ^
                           |
  I specified it! ----------

因此,在使用时,函数应该做什么没有歧义:

std::function<double(int)> blah = [](int x){ return x / 2.0f; };
aFunction(blah);
唉,编译器不会与我合作:

  

没有匹配的成员函数来调用'aFunction'

     

忽略了候选模板:无法匹配   '功能'对''(lambda at   file.hpp:274:16)'

有没有办法让这种情况发生?缺少模板专业化(这是一个非常泛型类),或者是一个虚拟参数(我还不是那么绝望)。

Pd积:

完全披露:上面只是问题的简化,正是我需要的是:

template <typename T>
class MyStuff {

    template <typename ReturnType>
    MyStuff<ReturnType> aFunction(std::function<ReturnType(T)> a){ 
        /*for each stuff in MyStuff do a(stuff)*/ 
    }
}

其中MyStuff包含T类型的属性和一堆inline函数,例如aFunction

1 个答案:

答案 0 :(得分:5)

如评论中所述,这有效:

#include <functional>

template <typename T>
struct MyStuff {
    template <typename ReturnType>
    MyStuff<ReturnType> aFunction(std::function<ReturnType(T)> a){ 
        return {};
    }
};

int main() {
    MyStuff<int> stuff;
    std::function<double(int)> fn = [](int) { return 0.; };
    stuff.aFunction(fn);
}

相反,这不起作用:

int main() {
    MyStuff<int> stuff;
    stuff.aFunction([](int) { return 0.; });
}

错误是问题中的错误:

  

注意:候选模板被忽略:无法匹配'function'与'(lambda at main.cpp:15:21)'

原因是类型推导仅适用于确切类型。不允许转换。在你的情况下,编译器应首先推导出lambda的所有返回类型,而不是以某种方式将其转换为std::function,最后从使用lambda构造的函数中推导出函数的返回类型。 这不是类型推导的工作方式。

您可以使用以下方法解决问题:

template <typename T>
struct MyStuff {
    template <typename F>
    auto aFunction(F &&f) -> MyStuff<decltype(std::forward<F>(f)(std::declval<T>()))> { 
        return {};
    }
};

Coliru上查看。