标签: generic-lambda

如何将前N个args传递给C++函数

我有这样的功能:

void loadData(std::function<void (std::string, std::string, std::string)> callback)
{
    // data loading stuff
    callback(body, subject, header);
}
Run Code Online (Sandbox Code Playgroud)

问题是我并不需要使用subject,并header在我的回调函数.现在我正在以这种方式处理它:

loadData([](std::string body, std::string, std::string){
    std::cout << body;
})
Run Code Online (Sandbox Code Playgroud)

我想用它替换它

loadData([](std::string body){
    std::cout << body;
})
Run Code Online (Sandbox Code Playgroud)

并自动传递给回调函数尽可能多的参数.我不想loadData为所有3个可能的参数计数手动重载函数.我也不想在调用站点上使用任何更复杂的lambda语法,因为我的库应该清楚,供其他人使用.这可能使用C++ STL和Boost吗?

lambda variadic-functions c++11 generic-lambda c++14

7
推荐指数
2
解决办法
386
查看次数

C++ 14:具有通用std :: function作为类成员的泛型lambda

考虑这个伪代码段:

class SomeClass
{
public:
    SomeClass()
    {
        if(true)
        {
            fooCall = [](auto a){ cout << a.sayHello(); };
        }
        else
        {
            fooCall = [](auto b){ cout << b.sayHello(); };
        }
    }
private:
    template<typename T>
    std::function<void(T)> fooCall;
};
Run Code Online (Sandbox Code Playgroud)

我想要的是一个fooCall存储泛型lambda 的类成员,而lambda又在构造函数中赋值.

编译器抱怨fooCall不能是模板化的数据成员.

关于如何在类中存储泛型lambda,有没有简单的解决方案?

c++ std-function generic-lambda c++14

7
推荐指数
1
解决办法
895
查看次数

使用任意数量的参数生成对lambdas的调用

事实证明,以下定义对我非常有用:

template<class Func, class... Args>
void apply_on_each_args(Func f, Args... args)
{
    (f(args), ...);
}
Run Code Online (Sandbox Code Playgroud)

基本上,在逗号运算符上折叠的参数包允许定义对带参数的函数的多个调用.例如:

apply_on_each_args([] (auto x) { cout << x << endl; }, 1, 2, "hello");
Run Code Online (Sandbox Code Playgroud)

将打电话给匿名lambda 1,2"hello".

提出这个想法,我想做同样的事情,但传递lambdas采取两个,三个等参数.例如,类似的东西

apply_on_each_args([] (auto x, auto y) { /* use x and y */ }, 1, 2, "hello",  "bye");
Run Code Online (Sandbox Code Playgroud)

任何能够实现它的线索,技术,想法等?

template-meta-programming variadic-templates generic-lambda fold-expression c++17

7
推荐指数
1
解决办法
185
查看次数

C++20模板lambas的限制和使用

C++ 标准专家的几个相关问题。

传入的 C++20引入了模板 lambdas ( P0428R2 )。

所以代替

auto x = [](auto x, auto y){ return x+y; };
Run Code Online (Sandbox Code Playgroud)

我们可以指定模板参数如下

auto x = []<typename T>(T x, T y){ return x+y; };
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好。

第一个问题:模板 lambda 中的显式模板参数是否只能从参数中推导出来,或者是否可以添加非推导出的模板参数?

阅读 P0428r1 我没有看到任何明确的限制,但是,我也没有看到非推导模板参数的例子。

在第一个近似值中,我认为非推导的模板参数是合法的,因为我看到以下愚蠢的代码

int main()
 {   
   []<int = 0>(){ }();
 }
Run Code Online (Sandbox Code Playgroud)

使用 g++(10.0.0 head)和 clang++(10.0.0 head)编译和运行。

假设允许非推导的模板参数,第二个问题是:如何在提供模板参数的同时调用模板 lambda?

举例:给定以下模板 lambda

auto x = []<std::size_t I>(auto t){ return std::get<I>(t); };
Run Code Online (Sandbox Code Playgroud)

I没有显式命名的情况下调用此类 lambda 时,是否有一些语法用于指定模板参数operator()

我试过

x<0u>(y);
Run Code Online (Sandbox Code Playgroud)

但 …

c++ lambda language-lawyer generic-lambda c++20

7
推荐指数
1
解决办法
273
查看次数

是否有一个std :: function类型或类似的lambda与auto参数?

当我将lambda分配给显式类型变量时(例如,当它是递归的时,为了捕获函数本身),我使用std::function.

以这个愚蠢的"位计数"函数为例:

std::function<int(int)> f;
f = [&f](int x){ return x ? f(x/2)+1 : 0; };
Run Code Online (Sandbox Code Playgroud)

当我们使用auto参数进行泛化时x,如C++ 14泛型lambda中所介绍的情况怎么样?

std::function<int(???)> f;
f = [&f](auto x){ return x ? f(x/2)+1 : 0; };
Run Code Online (Sandbox Code Playgroud)

很显然,我不能把autofunction类型参数.

是否有可能通常定义一个仿函数类来覆盖上面的确切情况,但仍然使用lambda作为函数定义?

(不要过度概括这一点,只接受一个自动参数并对返回值进行硬编码.)用例适用于上述场景:通过引用为递归调用捕获函数本身.

c++ lambda auto generic-lambda c++14

6
推荐指数
1
解决办法
836
查看次数

可变参数模板lambda参数的模板推导

给出以下可变参数模板:

template<typename... Params>
void fun(void(*f)(Params...), Params... params) {
  f(params...);
}

int main() {
  fun(+[](int a, int b) {}, 2, 3);
}
Run Code Online (Sandbox Code Playgroud)

现在,当fun使用lambda 调用时,我需要明确指定所有lambda参数的类型.这似乎是多余的,因为int, int可以从中推断出来2, 3.有没有办法让它更简洁自动?

我想以下工作,但它没有:

template<typename... Params>
void fun(void(*f)(Params...), Params... params) {
  f(params...);
}

int main() {
  fun(+[](auto a, auto b) {}, 2, 3);
}
Run Code Online (Sandbox Code Playgroud)

我正在编译g++ 5.4.0-std=c++14.

c++ lambda templates generic-lambda

6
推荐指数
1
解决办法
193
查看次数

通用lambda不能在命名空间中使用?

考虑以下代码

#include <iostream>
#include <functional>

namespace A {
    template<typename T>
    struct X {
        using Function = std::function<int(T)>;
        static Function f;
    };

    template<typename T>
    typename X<T>::Function X<T>::f = [](auto) { return 42; };

}

int main() {
    std::cout << A::X<int>::f(0);
}
Run Code Online (Sandbox Code Playgroud)

GCC和clang都接受此代码,但MSVC(测试版本19.00.23506)给出:

error C2888: 'auto <lambda_ce48e25aa4b9e3d225584044e4eae9e2>::operator ()(_T1) const': symbol cannot be defined within namespace 'A'

实际上,如果我删除命名空间A并在全局命名空间中定义所有内容,则接受代码.如果我使lambda表达式非泛型,则相同.

有人可以解释一下MSVC在这段代码中看到的问题是什么吗?C++ Standard是否限制在上面的上下文中使用泛型lambda?

c++ namespaces generic-lambda c++14

6
推荐指数
1
解决办法
421
查看次数

用于存储通用 lambda 的通用 std::function

当泛型 lambda 被存储为 a 时std::function,我们需要提供一个具体的类型,比如,

std::function<double(double)>
Run Code Online (Sandbox Code Playgroud)

因此绑定到特定类型,

以下声明:

std::function<auto(auto)>
Run Code Online (Sandbox Code Playgroud)

引发编译器错误。

我知道,从 c++14 开始,auto可用于存储 lambda 的返回值,但是在将 lambda 存储在std::function.

c++ lambda std-function generic-lambda c++14

6
推荐指数
1
解决办法
992
查看次数

lang声称通用lambda参数的constexpr成员不是constexpr

我想写一个通用的lambda作为变体的访客。此变体的成员包含constexpr成员值,我想在访问者中使用它。例如:

#include <variant>

template<int r>
struct S {
    constexpr static int this_r = r;
};

int f(std::variant<S<0>, S<1>, S<2> > v) {
    return std::visit([](auto const& arg) {
        if constexpr(arg.this_r == 0) { return 42; }
        else { return arg.this_r; }
    }, v);
}

int g() {
    std::variant<S<0>, S<1>, S<2> > x = S<2>();
    return f(x);
}
Run Code Online (Sandbox Code Playgroud)

GCC很高兴从7.1版本开始编译此代码。另一方面,Clang抱怨the的arg.this_r == 0参数if constexpr不是常量,可以回溯到4.0.0版本,但是在当前trunk中仍然存在。

谁在这里,我该如何避免这个问题(假设一个简单的对象if不会被剪裁,因为两个分支之一都无法实例化)?

附录:argClang作为值而不是const左值引用传递,很高兴,但是不幸的是,这不是我的选择。

c++ variant generic-lambda c++17

6
推荐指数
1
解决办法
70
查看次数

递归函数的返回类型推导

最近,我阅读了Barry对这个问题Recursive lambda functions in C++11的回答

template <class F>
struct y_combinator {
    F f; // the lambda will be stored here

    // a forwarding operator():
    template <class... Args>
    decltype(auto) operator()(Args&&... args) const {
        // we pass ourselves to f, then the arguments.
        // [edit: Barry] pass in std::ref(*this) instead of *this
        return f(std::ref(*this), std::forward<Args>(args)...);
    }
};
// deduction guide
template <class F> y_combinator(F) -> y_combinator<F>;
Run Code Online (Sandbox Code Playgroud)

基本上,y_combinator允许更轻松地编写递归 lambda 表达式(例如,无需 delcare a std::function)。当我玩的时候y_combinator,我发现了一些奇怪的东西: …

c++ template-argument-deduction generic-lambda c++17

6
推荐指数
1
解决办法
182
查看次数