autofuntionTimesMod1(int mod) {
int variableA = mod;
auto f = [variableA](int a, int b) { return a % variableA * b % variableA; };
return f;
}
voidtest1() {
cout <<"---test1---"<< endl;
int a =10, b =20, c =7;
auto times = funtionTimesMod1(c);
cout << times(a, b) << endl;
}
autofuntionTimesMod2(int mod) {
int variableA = mod;
auto f = [&variableA](int a, int b) { return a % variableA * b % variableA; };
return f;
}
voidtest2() {
cout <<"---test2---"<< endl;
int a =10, b =20, c =7;
auto times = funtionTimesMod2(c);
cout << times(a, b) << endl;
}
这段代码就已经不能正常工作了,它的输出是 0.
我们来看看为啥:
Process 15820 stopped
* thread #1, name = 'tmp', stop reason = step in
frame #0: 0x000000000040096b tmp`funtionTimesMod2(mod=7) at tmp.cpp:17
14 }
15
16 auto funtionTimesMod2(int mod) {
-> 17 int variableA = mod;
18 auto f = [&variableA](int a, int b) { return a % variableA * b % variableA; };
19 return f;
20 }
(lldb) p &variableA
(int *) $1 = 0x00007fffffffe120
Process 15820 stopped
* thread #1, name = 'tmp', stop reason = step over
frame #0: 0x00000000004009dc tmp`test2() at tmp.cpp:25
22 cout << "---test2---" << endl;
23 int a = 10, b = 20, c = 7;
24 auto times = funtionTimesMod2(c);
-> 25 cout << times(a, b) << endl;
26 }
27 auto funtionTimesMod3(int mod) {
28 int variableA = mod;
(lldb) p times
((anonymous class)) $2 = {
variableA = 0x00007fffffffe120
}
autofuntionTimesMod5(int mod) {
INT variableA;
cout <<"----A"<< endl;
variableA.num = mod;
cout <<"----B"<< endl;
classfunction {
const INT variableA;
public:
function(const INT &variableA) : variableA(variableA) {}
intoperator()(int a, int b) {
cout <<"----C"<< endl;
return a % variableA.num * b % variableA.num;
}
};
function f = function(variableA);
cout <<"----D"<< endl;
return f;
}
voidtest5() {
cout <<"---test5---"<< endl;
int a =10, b =20, c =7;
cout <<"----E"<< endl;
auto times = funtionTimesMod5(c);
cout <<"----F"<< endl;
cout << times(a, b) << endl;
cout <<"----G"<< endl;
}
实际上没必要纠结那么多,正常编译的话,其实是不会去先建一个右值的对象的.
代码
#include<bits/stdc++.h>usingnamespace std;
autofuntionTimesMod1(int mod) {
int variableA = mod;
auto f = [variableA](int a, int b) { return a % variableA * b % variableA; };
return f;
}
voidtest1() {
cout <<"---test1---"<< endl;
int a =10, b =20, c =7;
auto times = funtionTimesMod1(c);
cout << times(a, b) << endl;
}
autofuntionTimesMod2(int mod) {
int variableA = mod;
auto f = [&variableA](int a, int b) { return a % variableA * b % variableA; };
return f;
}
voidtest2() {
cout <<"---test2---"<< endl;
int a =10, b =20, c =7;
auto times = funtionTimesMod2(c);
cout << times(a, b) << endl;
}
classINT {
public:int num;
INT(const INT &i) : num(i.num) { cout <<"Copy constructor"<< endl; }
INT() =default;
};
autofuntionTimesMod3(int mod) {
INT variableA;
cout <<"----A"<< endl;
variableA.num = mod;
cout <<"----B"<< endl;
auto f = [variableA](int a, int b) {
cout <<"----C"<< endl;
return a % variableA.num * b % variableA.num;
};
cout <<"----D"<< endl;
return f;
}
voidtest3() {
cout <<"---test3---"<< endl;
int a =10, b =20, c =7;
cout <<"----E"<< endl;
auto times = funtionTimesMod3(c);
cout <<"----F"<< endl;
cout << times(a, b) << endl;
cout <<"----G"<< endl;
}
autofuntionTimesMod4(int mod) {
INT variableA;
cout <<"----A"<< endl;
variableA.num = mod;
cout <<"----B"<< endl;
classfunction {
const INT variableA;
public:
function(const INT &variableA) : variableA(variableA) {}
intoperator()(int a, int b) {
cout <<"----C"<< endl;
return a % variableA.num * b % variableA.num;
}
} f(variableA);
cout <<"----D"<< endl;
return f;
}
voidtest4() {
cout <<"---test4---"<< endl;
int a =10, b =20, c =7;
cout <<"----E"<< endl;
auto times = funtionTimesMod4(c);
cout <<"----F"<< endl;
cout << times(a, b) << endl;
cout <<"----G"<< endl;
}
autofuntionTimesMod5(int mod) {
INT variableA;
cout <<"----A"<< endl;
variableA.num = mod;
cout <<"----B"<< endl;
classfunction {
const INT variableA;
public:
function(const INT &variableA) : variableA(variableA) {}
intoperator()(int a, int b) {
cout <<"----C"<< endl;
return a % variableA.num * b % variableA.num;
}
};
function f = function(variableA);
cout <<"----D"<< endl;
return f;
}
voidtest5() {
cout <<"---test5---"<< endl;
int a =10, b =20, c =7;
cout <<"----E"<< endl;
auto times = funtionTimesMod5(c);
cout <<"----F"<< endl;
cout << times(a, b) << endl;
cout <<"----G"<< endl;
}
intmain() {
test1();
test2();
test3();
test4();
test5();
}
在一次偶然的机会,我看到了一篇介绍 C++ 17 中的 if constexpr 的用法,可以在编译期进行一些计算,虽然我很早就知道了 constexpr 的用法,但是大家举的例子基本上都是数值计算,让编译器在编译期间将数值进行计算,从而减轻运行时的消耗,我也从来想到其他用法,所以一直没有在项目中使用到。
# lxz @ lxz-MacBook-Pro in ~/Develop/constexpr-demo/build on git:master o [13:28:39]
$ cmake ../ -G Ninja -DENABLE_MODULE=ON
-- The CXX compiler identification is AppleClang 13.0.0.13000029
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/lxz/Develop/constexpr-demo/build
# lxz @ lxz-MacBook-Pro in ~/Develop/constexpr-demo/build on git:master o [13:28:45]
$ ninja
[2/2] Linking CXX executable src/constexpr
# lxz @ lxz-MacBook-Pro in ~/Develop/constexpr-demo/build on git:master o [13:28:48]
$ ./src/constexpr
Now Enable Module
# lxz @ lxz-MacBook-Pro in ~/Develop/constexpr-demo/build on git:master o [13:28:52]
$ cmake ../ -G Ninja -DENABLE_MODULE=OFF
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/lxz/Develop/constexpr-demo/build
# lxz @ lxz-MacBook-Pro in ~/Develop/constexpr-demo/build on git:master o [13:28:58]
$ ninja
[2/2] Linking CXX executable src/constexpr
# lxz @ lxz-MacBook-Pro in ~/Develop/constexpr-demo/build on git:master o [13:29:00]
$ ./src/constexpr
Now Disable Module