1
fgwmlhdkkkw OP 有编译器会尝试把这种写法变成一个循环吗?
|
2
codehz 2022-04-14 16:31:26 +08:00 via Android 1
你写类定义里默认就是 inline ,用模板基本上逃不了 inline 了,然后 inline 的语义是允许在不同翻译单元重复定义,不是“不生成函数原地展开”,能不能展开看编译器心情
|
3
lonewolfakela 2022-04-14 16:35:01 +08:00 1
1 、你写的这个不就是变长参数?
2 、是。 3 、几乎没啥影响……可能让某些编译器的优化步骤中对函数内联稍微激进一点点,但是效果可以忽略不计。 4 、尾递归确实很可能被优化掉,但是优化器的事情没人敢打包票;虽然我觉得如果你这个实际跑起来没啥问题的话就这样也挺好。 5 、真要是觉得递归看起来实在难看的话,可以学习一下 https://en.cppreference.com/w/cpp/language/fold 的用法 6 、你为什么不把变长参数放在一个 std::vector 里传进去呢…… |
4
fgwmlhdkkkw OP @codehz #2 我一直以为 inline 是“尽可能的 define”。
@lonewolfakela #3 谢谢,vector 的话,我要为数字和字符串做一个包装类。问题是在这个包装类里怎么储存字符串?(我不想复制)。 |
5
cnbatch 2022-04-14 17:31:26 +08:00
不想复制的话,可以使用万能引用、完美转发
template <typename T, typename ... Args> [[nodiscard]] const Value * peek(const Value * src, T key, Args && ... args) { // auto 和 if 的部分 // ...... return peek(ptr, std::forward<Args>(args)...); } |
6
fgwmlhdkkkw OP @cnbatch #5 额,左值右值,值晕了~
|
7
whitehack 2022-04-14 17:47:40 +08:00
感觉已经完全不会 c++了.
这 [[nodiscard]] 是啥语法.. 还是两个 中括 |
8
fgwmlhdkkkw OP @whitehack #7 ……Clion 教我加的😓
|
9
fgwmlhdkkkw OP @whitehack #7 意思是,调用者不能忽略这个函数的返回值。
|
10
cnbatch 2022-04-14 18:03:19 +08:00 1
@whitehack [[nodiscard]]的意思楼上已经说了,那我就稍作补充。
这是 C++17 新属性 en.cppreference.com/w/cpp/language/attributes/nodiscard 很快就连 C 语言也能用上这个属性( C23 ) en.cppreference.com/w/c/language/attributes/nodiscard |
11
cnbatch 2022-04-14 18:38:31 +08:00
@fgwmlhdkkkw 忘了补一个 T key 的万能引用
const Value * peek(const Value * src, T key, Args && ... args) 可以适当改成 const Value * peek(const Value * src, T && key, Args && ... args) { auto ptr = peek(src, std::forward(key)); if (ptr == nullptr) return nullptr; return peek(ptr, std::forward<Args>(args)...); } 至于应不应该改,那就视乎你的具体需要而定 |
12
lonewolfakela 2022-04-14 22:53:24 +08:00
@fgwmlhdkkkw #4 我不太明白你的“不想复制”指的是啥。就我看来你这里用一个 std::vector<std::variant<std::string,int>>就能满足需求了的样子?
|
13
fgwmlhdkkkw OP @lonewolfakela #12 你不说我都不知道,c++也有 union……谢谢
|
14
fgwmlhdkkkw OP @lonewolfakela #12 那其实所有的变长参数都可以写成这种 vector ,应该要比模板展开好吧?
|
15
lonewolfakela 2022-04-15 10:19:40 +08:00
@fgwmlhdkkkw #14 仅就你这个应用场景,我觉得 vector 更好。但是也有一些其他场景下更适合用模板,不然函数用起来会很难看(参考 https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification ,这种 format 函数如果参数也用 vector 来传的话用起来肯定特别难受)。
不过总的一般原则是优先考虑代码写起来美观、顺手,而不是优先考虑编译器会不会内联、编译出来的代码快不快之类问题;性能问题一般不要过早优化,代码写出来了如果确定有性能瓶颈的话再针对性优化。 |
16
fgwmlhdkkkw OP @lonewolfakela #12 variant 和 optinal 一样,只能保存值,不能保存引用。那所有的字符串不都会 copy 一下吗?
|
17
fgwmlhdkkkw OP @fgwmlhdkkkw #16 我可以用`const char*`,可以了,只是多写一组大括号,完美。
|
18
lonewolfakela 2022-04-15 18:05:06 +08:00
@fgwmlhdkkkw #16 如果你是想保存引用的话,那你需要 std::vector<std::variant<std::reference_wrapper<std::string>,int>>
|