- 主题:今天看见一个完全看不懂的写法
main里啥代码也没
happy@ubuntu:~$ $CXX -static -O0 -std=c++2a 1.cpp
happy@ubuntu:~$ gdb -batch -ex 'file a.out' -ex 'disassemble main'
Dump of assembler code for function main:
0x000000000040226d <+0>: push %rbp
0x000000000040226e <+1>: mov %rsp,%rbp
0x0000000000402271 <+4>: mov $0x0,%eax
0x0000000000402276 <+9>: pop %rbp
0x0000000000402277 <+10>: ret
End of assembler dump.
happy@ubuntu:~$ $CXX -v
Using built-in specs.
COLLECT_GCC=/opt/cross/bin/x86_64-linux-musl-g++
COLLECT_LTO_WRAPPER=/opt/cross/bin/../libexec/gcc/x86_64-linux-musl/12.2.0/lto-wrapper
Target: x86_64-linux-musl
--
FROM 222.131.205.*
你说得对
o(1.3);
o("test");
【 在 puke 的大作中提到: 】
: 没调用就没代码
: 加个 o();就有了。
--
FROM 222.131.205.*
试了17能编译,14不能
【 在 urbeautiful 的大作中提到: 】
: 就是多继承啊,这个o类继承多个仿函数类,然后using是把父类的函数带到子类可见,不过这个需要20才能编译吧,17标准的话还需要写一个deduction guide吧 。
--
FROM 222.131.205.*
chatgpt分析的:
这段代码使用了 C++17 中引入的类模板的折叠表达式(fold expressions)和变量模板(variable template)特性。
Overloader 是一个类模板,使用了可变参数模板(variadic template),接受任意数量的类型参数 Ts...。类模板 Overloader 继承了每个 Ts 类型的所有成员,通过使用 Ts::operator()... 来暴露所有基类的 operator()。
在 main 函数中,使用了 C++17 中引入的变量模板(variable template)特性,定义了一个名为 o 的变量,类型为 Overloader 的实例,其中 Ts... 被推导为包含两个参数类型的模板参数包 { [] (auto const& a) {std::cout << a;}, [] (float f) {std::cout << std::setprecision(3) << f;} }。这个变量模板的推导结果为 Overloader<lambda_1_type, lambda_2_type>,其中 lambda_1_type 和 lambda_2_type 是两个 lambda 表达式的类型。
在这个代码中,编译器使用了模板参数推导的规则,根据变量模板的初始化器中的参数类型推导出 Overloader 的模板参数 Ts...,从而推导出变量 o 的类型。在这个过程中,编译器使用了多个 C++17 中引入的特性,包括折叠表达式和变量模板。
chatgpt说的这个"variable template"是c++14引入的,不是c++17引入的。
https://en.cppreference.com/w/cpp/language/variable_template
所以这段代码的黑魔法除了parameter pack外,是靠variable template的自动类型推导。
--
修改:z16166 FROM 222.131.205.*
FROM 222.131.205.*
奇怪,楼主为啥要少写这个deduction guide
我进这个网页复制了代码,没仔细看,直接-std=c++17编译过去了,还以为复制的和楼主的代码一样呢。
【 在 ble 的大作中提到: 】
: 进链接看了,楼主少写了模板推导指引
: template<typename... T>
: Overloader(T...) -> Overloader<T...>;
: ...................
--
FROM 222.131.205.*