C++ 中的可调用对象与其他编程语言中的函数对象有何异同?
ringa_lee
ringa_lee 2017-04-17 14:35:30
0
1
413

C++ 中的可调用对象与其他编程语言中的函数对象有何异同?

ringa_lee
ringa_lee

ringa_lee

reply all(1)
迷茫

The question asked about other languages, which is too broad, because there are so many programming languages, including traditional functions like C language, functions that cannot exist independently like Java, and different forms of various scripting languages. function.

But in a language where functions are first-class citizens, functions are required to do this

  • Functions can exist independently and can be executed anywhere

  • The scope of the function is lexical scope and can capture external variables

  • A function can be returned from another function or used as a parameter of another function (higher-order function)

  • After a function is generated from another function, the referenced scope is still accessible instead of being destroyed

In many scripting languages ​​and emerging languages, most functions have the above characteristics.

Regarding the issue of closure capture in different languages, you can refer to an article I wrote before https://zhuanlan.zhihu.com/p/...

Let’s talk about C++. C++ has four things that can be called

  1. Function

  2. Function pointer

  3. Classes that overload the () operator

  4. lambda

The types of these four things are different, but they can all be used to execute functions, and they are all in the same form as func().

Function and function pointer can be converted to each other under certain circumstances. It exists in C language, but it has some problems that are difficult to solve, including

  • Function types are difficult to write and read

  • State cannot be saved inside the function, and there is no way to capture outer variables

A class that overloads the () operator is a functor writing method provided by C++, which can implement many methods

class Test{
public:
 Test(int a):_a(a){}
 int operator ()(int b){  
    return _a+b;
 }  
private:
  int _a;
};

Just use this:

Test sum1 = Test(1);
std::cout << sum1(10) << '\n';
Test sum2 = Test(10);
std::cout << sum2(10) << '\n';

You can see that both sum1 and sum2 save a state internally, and then behave differently. This is something that ordinary functions and function pointers cannot do.

However, a major disadvantage of classes that overload the () operator is that they are not lightweight enough. There is a gap between them and functions/function pointers in terms of space usage and execution efficiency.

C++11 introduced lambda, a typical lambda is like this

int a = 10;
auto func = [&a](int b){return a+b;};
std::cout << func(10) << '\n';
a = 20;
std::cout << func(10) << '\n';

You can see that lambda can easily capture variables and achieve closure effects, so we can use lambda in many situations to replace classes that overload the () operator.

However, lambda also has limitations. First of all, its type cannot be written manually, which means that for the same two lambdas, its type is different

auto func = [&a](int b){return a+b;};
auto func2 = [&a](int b){return a+b;};
std::cout << (typeid(func).name() !=  typeid(func2).name()) << '\n';

So we can only use auto when defining, and if we want to store lambda in a vector, list, etc. container, we must use the packaging class std::function, which is essentially a generic template class , the () operator is also overloaded

std::function<int(int)> func3 = func;

After using std::function, the lightweight advantage of lambda disappears, but sometimes it has to be done.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template