如何将 lambda 传递给模板参数

How to pass a lambda to a template paramater

我正在尝试定义一个函数 func(),其中 returns 一个 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++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;
}

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

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