【问题标题】:How to pass a lambda to a template paramater如何将 lambda 传递给模板参数
【发布时间】:2021-06-25 15:44:48
【问题描述】:

我正在尝试定义一个函数func(),它返回一个std::string

template<typename T = std::string, template<typename> typename F = decltype([](const T &t){return t;})>
std::string func(const T &t){
    F f;
    return f(t);
}

如您所见,我要做的是传递一个 lambda 作为模板参数,以便我可以像这样调用函数 func()

func<int, decltype([](int a){return std::to_string(a);})>(2);

另外,我为模板参数设置了默认值,这样我就可以这样调用它:

func<>("abc");

但是,上面的代码给了我一个错误:

<source>:39:54: error: expected unqualified-id before 'decltype'
   39 | template<typename T, template<typename> typename F = decltype([](const T &t){return t;})>
      |                                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:39:54: error: invalid default argument for a template template parameter
<source>:39:54: error: expected '>' before 'decltype'

顺便说一句,我的 C++ 版本是 C++11。

【问题讨论】:

  • 您使用的是什么版本的 C++? IIRC C++20 让这变得更容易了。
  • 如果它是非捕获的,则将默认设置为函数指针。或者完全不使用默认设置。
  • 我不确定这是否算作重复,但this 是否回答了您的问题?
  • 为什么要将 lambda 作为模板参数传递,而不是仅仅作为函数参数传递?

标签: c++ c++11 templates lambda template-argument-deduction


【解决方案1】:

在 C++11 中?使用 lambda 作为模板参数?

鉴于 lambda(在 C++20 之前)不能在未评估的上下文中使用(所以在 decltype() 中)并且不能默认构造,我看不到方法。

我能想象的最好的,在 C++11 中,重现类似的东西如下

template <typename T, typename F = std::function<std::string(T const &)>>
std::string func (T const & t, F f = [](const T &t){return std::string{t};})
 { return f(t); }

你可以只用第一个参数调用

func("abc");

假设您接受默认 lambda(但保存为 std::function)。

如果你不喜欢默认的,你也可以传递另一个 lambda

func(1, [](int const &){ return "one"; });

但作为传统参数,而不是模板参数。

【讨论】:

    【解决方案2】:

    在 C++11 中,您不能在未评估的上下文中使用 lambda 表达式,因此我认为您必须以不同的方式实现它。

    C++20 添加了这个特性,所以这里有一个可以在 C++20 中编译和运行的示例。

    #include <iostream>
    #include <string>
    
    
    template<typename T = std::string, typename F = decltype([](const T &t)->std::string{return t;})>
    std::string func(const T &t){
        F f;
        return f(t);
    }
    
    
    
    int main() {
        // convert int to string
        std::cout << func<int, decltype([](int a){return std::to_string(a);})>(2) << std::endl;
        // take float parameter, but just ignore the parameter
        std::cout << func<float, decltype([](float a){return "ignore the param";})>(2.2) << std::endl;
        // default lambda
        std::cout << func("abc") << std::endl;
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-07
      • 1970-01-01
      • 2016-08-21
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      相关资源
      最近更新 更多