这里有一段代码,有一些小细节,不是很明白。请教一下

2021-04-30 09:05:15 +08:00
 yazoox
// 1
struct Base
{
    int retCode {};
    std::string retErrorString;
};

// 2
template <typename Type>
struct EventResult : Base
{
    Type retValue {};
};

// 3
template <>
struct EventResult<void> : Base {};

代码段 1 中间的 int retCode 后面为什么要添加一对{},代码 2 也有类似的,Type retValue {} 代码段 2 已经定义好了模板,为什么要添加代码段 3 ?

3037 次点击
所在节点    C++
24 条回复
leimao
2021-04-30 09:10:56 +08:00
1 和 2 是 C++ Explicit Constructor,语法规范,减少歧义。但是他这个{}里面不放个数,也是挺 confusing 的。
https://leimao.github.io/blog/CPP-Explicit-Constructor/
leimao
2021-04-30 09:13:53 +08:00
3 感觉就是给 void 这个 type 弄一个特殊的 definition 。
因为
```
void retValue {};
```
是会报错的。
jonah
2021-04-30 09:17:25 +08:00
@leimao initializer_list 不放个数,表示调用默认构造。
leimao
2021-04-30 09:18:56 +08:00
@jonah 个人认为这个是不好的习惯,必须改掉。
3dwelcome
2021-04-30 09:44:44 +08:00
一楼说的对。
可这代码需要加--std=c++xx, 如果不加,编译就直接报:error C2063: 'retCode' : not a function

总觉得直接写 int retCode = {0},大家也能猜到是调用构造函数啊,一缩写反而看不太懂。
bestwaytowait
2021-04-30 09:46:10 +08:00
其实这个算 Uniform Initialization
Tony042
2021-04-30 09:47:56 +08:00
@leimao initializer_list 置空是没问题的,书上有大量这样的写法,主要是默认初始化一切变量,尤其是指针,要是指针不置为 nullptr,碰巧指向内存里的一处位置,后续很可能会出现奇奇怪怪的 bug 。
lonewolfakela
2021-04-30 09:48:41 +08:00
@leimao 使用 empty initializer 进行初始化叫做 Value initialization ( https://en.cppreference.com/w/cpp/language/value_initialization ),对于整数类型,Value initialization 意味着初始化为 0 值(Zero initialization,https://en.cppreference.com/w/cpp/language/zero_initialization)。这是很常见的用法,不知道为什么你认为是不好的习惯呢?
Tony042
2021-04-30 09:51:11 +08:00
@leimao 3 这个这个叫做 curiously recurring template pattern,CRTP,是用来实行静态多态的,实现和虚函数相似的效果,但避免虚函数带来的性能损失。
lonewolfakela
2021-04-30 09:52:55 +08:00
@Tony042 这是哪门子的 CRTP,Base 又不是模板类……
Tony042
2021-04-30 09:53:37 +08:00
@lonewolfakela 学艺不精,sorry,sorry,没细看
bestwaytowait
2021-04-30 09:53:52 +08:00
@Tony042 不是啊,CRTP 是 template base
Tony042
2021-04-30 09:54:57 +08:00
@lonewolfakela
@bestwaytowait
3 这个是不是就是一个模板偏特化?
lonewolfakela
2021-04-30 09:56:12 +08:00
@Tony042 是啊,2 楼说的很清楚了,因为成员 retValue 的类型不可能是 void,所以必须单独给 void 弄一个没有 retValue 的特化。
lonewolfakela
2021-04-30 09:58:37 +08:00
@3dwelcome retCode 那里不同的人对于到底用“int retCode = 0”更好还是“int retCode{}”更好可能还会有些争论,但是代码段 2 里那个“Type retValue {}”,因为不知道 Type 的类型是啥,所以还真就只能这么写了……
greatbody
2021-04-30 10:14:08 +08:00
为啥现在人都说“小细节”而不说“细节”

以后是不是要说“特别微小细微的细节”?
bestwaytowait
2021-04-30 10:17:18 +08:00
@greatbody 确实套娃了 =。= 哈哈哈哈
yazoox
2021-04-30 10:36:46 +08:00
@leimao
3 不是“多余”的?我如果需要使用 type 为 void 的,我直接使用 EventResult<void>不就可以了么?干嘛要单独写一行,特别 definition 一下?
yazoox
2021-04-30 10:39:33 +08:00
@lonewolfakela
“因为成员 retValue 的类型不可能是 void”
为什么?模板的定义 Type retValue {}; 就是有可能是 void 啊?
尤其是,再单独使用代码段 3,和直接使用代码 2 EventResult<void>不是一样的么?单独定义,retValue 的类型就可以为 void 了?
yazoox
2021-04-30 10:51:45 +08:00
@leimao
我看了一下你分享的链接,
int retCode {} 是初始化,retCode 和 {} 中间可以添加“空格”,我以为必须连续...... int retCode{}

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/774256

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX