gpt4 book ai didi

c++ - Lambda 函数作为基类

转载 作者:IT老高 更新时间:2023-10-28 12:11:12 25 4
gpt4 key购买 nike

在玩 Lambdas 时,我发现了一个我不完全理解的有趣行为。

假设我有一个从 2 个模板参数派生的 struct Overload,并且有一个 using F1::operator(); 子句。

现在,如果我从两个仿函数派生,我只能访问 F1 的 operator()(如我所料)

如果我从两个 Lambda 函数派生,这将不再正确:我也可以从 F2 访问 operator()。

#include <iostream>

// I compiled with g++ (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8)
//
// g++ -Wall -std=c++11 -g main.cc
// g++ -Wall -std=c++11 -DFUNCTOR -g main.cc
//
// or clang clang version 3.3 (tags/RELEASE_33/rc2)
//
// clang++ -Wall -std=c++11 -g main.cc
// clang++ -Wall -std=c++11 -DFUNCTOR -g main.cc
//
// on a Linux localhost.localdomain 3.9.6-200.fc18.i686 #1 SMP Thu Jun 13
// 19:29:40 UTC 2013 i686 i686 i386 GNU/Linux box


struct Functor1
{
void operator()() { std::cout << "Functor1::operator()()\n"; }
};

struct Functor2
{
void operator()(int) { std::cout << "Functor2::operator()(int)\n"; }
};

template <typename F1, typename F2>
struct Overload : public F1, public F2
{
Overload()
: F1()
, F2() {}

Overload(F1 x1, F2 x2)
: F1(x1)
, F2(x2) {}

using F1::operator();
};

template <typename F1, typename F2>
auto get(F1 x1, F2 x2) -> Overload<F1, F2>
{
return Overload<F1, F2>(x1, x2);
}


int main(int argc, char *argv[])
{
auto f = get(Functor1(), Functor2());

f();
#ifdef FUNCTOR
f(2); // this one doesn't work IMHO correctly
#endif

auto f1 = get(
[]() { std::cout << "lambda1::operator()()\n"; },
[](int) { std::cout << "lambda2::operator()(int)\n"; }
);
f1();
f1(2); // this one works but I don't know why


return 0;
}

标准规定:

The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed non- union class type

所以每个 Lambda 的类型都应该是唯一的。

我无法解释为什么会这样:有人能解释一下吗?

最佳答案

除了 operator() 之外,由 lambda 定义的类可以(在适当的情况下)提供到函数指针的转换。情况(或至少是主要情况)是 lambda 无法捕获任何内容。

如果您添加捕获:

auto f1 = get(
[]() { std::cout << "lambda1::operator()()\n"; },
[i](int) { std::cout << "lambda2::operator()(int)\n"; }
);
f1();
f1(2);

...不再提供到 pointer to function 的转换,因此尝试编译上面的代码会给出您可能一直预期的错误:

trash9.cpp: In function 'int main(int, char**)':
trash9.cpp:49:9: error: no match for call to '(Overload<main(int, char**)::<lambda()>, main(int, char**)::<lambda(int)> >) (int)'
trash9.cpp:14:8: note: candidate is:
trash9.cpp:45:23: note: main(int, char**)::<lambda()>
trash9.cpp:45:23: note: candidate expects 0 arguments, 1 provided

关于c++ - Lambda 函数作为基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18432260/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com