【问题标题】:Can I use variadic templates in a lambda?我可以在 lambda 中使用可变参数模板吗?
【发布时间】:2014-06-07 10:26:56
【问题描述】:

我可以做这个吗?

假想语法:

auto foo = [] () { };
template <class T, typename ... Args>
auto foo =
[&] (T && V, Args && ... args) {
    do_something(V);
    foo(std::forward<Args>(args)...);
};

【问题讨论】:

  • 我认为 C++14 可以让你这样做:coliru.stacked-crooked.com/a/386d6f281077b336
  • 你会如何使用它?它看起来有点像变量模板(在 C++1y 的块范围内是不允许的)。作为多态 lambda,请参阅 chris 的解决方案。在 C++11 中,您可以将其实现为成熟的函数对象类。
  • foo 的伪递归调用存在一些问题:标识符可能不会出现在带有auto 的声明的初始化程序中。 (另外,你不能重载 lambda,但我想这是问题的一部分。)
  • @chris 您可以将此(多态可变参数 lambda)与(本地)函数对象类型结合起来以实现重载和此伪递归。我认为这是一个答案。
  • @dyp,我还没有使用可变参数 lambda 来做任何有用的事情。我很乐意看到你的想法作为答案充实起来。

标签: c++ templates c++11 lambda variadic-templates


【解决方案1】:

正如 cmets 中提到的,您不能真正做到这一点,因为 lambda 不够强大。

[](auto val){} 语法被允许时,这会容易得多。

我使用以下内容对元组进行基本调用。:

template<typename Tuple_t, typename Func_t, std::size_t k_index = 0>
//Only come here if the passed in index is less than sie of tuple
    typename std::enable_if<k_index <  tuple_size<Tuple_t>::value>::type 
    call_over_tuple(Tuple_t& irk_tuple, Func_t i_func){

    i_func(get<k_index>(irk_tuple));
    call_over_tuple<Tuple_t, Func_t, k_index + 1>(irk_tuple, i_func);

}

template<typename Tuple_t, typename Func_t, std::size_t k_index>
typename std::enable_if < k_index >=  tuple_size<Tuple_t>::value>::type
    call_over_tuple(Tuple_t& irk_tuple, Func_t i_func){
             //do nothing
}

将此扩展为仅随机参数给出。

template<typename Func_t, typename ...Args>
void call_over_vals(Func_t i_func, Args&&... i_args){

    auto arg_tuple = make_tuple(forward<Args>(i_args)...);

    call_over_tuple<decltype(arg_tuple), Func_t>(arg_tuple, i_func);
}

为了实现函数重载或模板,您需要创建一个调用类来执行您的操作。

template<typename T>
void do_something(const T& irk_val){
    cout << irk_val;
}

class caller_class{
public:

    template<typename T>
    void operator()(const T& i_val){
        do_something(i_val);
    }
private:

};

void print_integer(int i_val){
    cout << i_val;
}

int main(int argv, char** argc){

    call_over_vals(caller_class(), 3, ' ' ,  2, " asdf ", 4, "\n");


    //If you know the argument type just pass it in
    call_over_vals(print_integer, 1, 2, 3, 4, 5);

    cout << "\n";

    call_over_vals([](int y_val){cout << y_val; }, 1, 2, 3, 4, 5);
}

输出:

3 2 asdf 4
12345
12345

【讨论】:

    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 2015-12-01
    • 2017-11-13
    • 2021-12-26
    • 1970-01-01
    • 2018-07-31
    • 1970-01-01
    相关资源
    最近更新 更多