【问题标题】:Parametrize using a template parameter as a parameter to a lambda使用模板参数作为 lambda 的参数进行参数化
【发布时间】:2020-03-16 18:07:16
【问题描述】:

我希望能够有一些仿函数作为函数的参数。

仿函数的参数应该是模板化的,所以我可以调用其他依赖于它的类型的函数。

这是我目前所拥有的:

using namespace std;
template<typename T, typename PredT>
void foo(PredT pred)
{
    for(size_t i=0; i< 3; i++)
    {
        std::function<void(T)> predImpl(pred);
        T t{};
        predImpl(t);
    }
}


template<typename T>
void foo2(std::function<void(T)> func)
{
    for(size_t i=0; i< 3; i++)
    {
        T t{}; //there's obviously other logic that produces those;
        func(t);
    }
}

int main()
{     
    //foo([](int x) {cout << x << '\n';}); //error: no matching function for call to 'foo(main()::<lambda(int)>)
    // foo([](int x) {cout << x << '\n';}); doesn't work  error: no matching function for call to 'foo(main()::<lambda(int)>)' 
    foo2(std::function<void(int)>([](int x) {cout << x << '\n';})); // syntax is ugly, requires an explicit conversion to std::function

}

我基本上想根据 lambda 的参数推断出 T,但我不知道这是否可能。

使用显式 std::function 转换的解决方案可行,但它很麻烦,并且有点失去了仅使用 lambda 的便利性。

【问题讨论】:

  • 问题是参数推导。模板不能根据这个模板定义和用法推导出T。这里是simple fix。现在的问题是可以从PredT 中推断出T 吗?我不这么认为。
  • 是的,我想避免提及具体类型,但听起来无法推断,您是否碰巧知道哪个规则不符合该场景?

标签: c++ templates c++14


【解决方案1】:

如果你不需要支持泛型 lambda,你可以这样做:

template <typename C, typename R, typename T>
T detectParameterType(R (C::*)(T));
template <typename C, typename R, typename T>
T detectParameterType(R (C::*)(T) const);

template<typename PredT>
void foo(PredT pred)
{
    using T = decltype(detectParameterType(&PredT::operator()));
    T t{};
    pred(t);
}

Demo

泛型 lambda 可以接受任何类型的参数,因此自然不可能推断出参数类型 - 没有可推断的单一类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    相关资源
    最近更新 更多