// 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 ?
1
leimao 2021-04-30 09:10:56 +08:00
1 和 2 是 C++ Explicit Constructor,语法规范,减少歧义。但是他这个{}里面不放个数,也是挺 confusing 的。
https://leimao.github.io/blog/CPP-Explicit-Constructor/ |
2
leimao 2021-04-30 09:13:53 +08:00
3 感觉就是给 void 这个 type 弄一个特殊的 definition 。
因为 ``` void retValue {}; ``` 是会报错的。 |
5
3dwelcome 2021-04-30 09:44:44 +08:00
一楼说的对。
可这代码需要加--std=c++xx, 如果不加,编译就直接报:error C2063: 'retCode' : not a function 总觉得直接写 int retCode = {0},大家也能猜到是调用构造函数啊,一缩写反而看不太懂。 |
6
bestwaytowait 2021-04-30 09:46:10 +08:00
其实这个算 Uniform Initialization
|
7
Tony042 2021-04-30 09:47:56 +08:00
@leimao initializer_list 置空是没问题的,书上有大量这样的写法,主要是默认初始化一切变量,尤其是指针,要是指针不置为 nullptr,碰巧指向内存里的一处位置,后续很可能会出现奇奇怪怪的 bug 。
|
8
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)。这是很常见的用法,不知道为什么你认为是不好的习惯呢?
|
9
Tony042 2021-04-30 09:51:11 +08:00
@leimao 3 这个这个叫做 curiously recurring template pattern,CRTP,是用来实行静态多态的,实现和虚函数相似的效果,但避免虚函数带来的性能损失。
|
10
lonewolfakela 2021-04-30 09:52:55 +08:00
@Tony042 这是哪门子的 CRTP,Base 又不是模板类……
|
11
Tony042 2021-04-30 09:53:37 +08:00
@lonewolfakela 学艺不精,sorry,sorry,没细看
|
12
bestwaytowait 2021-04-30 09:53:52 +08:00
@Tony042 不是啊,CRTP 是 template base
|
13
Tony042 2021-04-30 09:54:57 +08:00
|
14
lonewolfakela 2021-04-30 09:56:12 +08:00
@Tony042 是啊,2 楼说的很清楚了,因为成员 retValue 的类型不可能是 void,所以必须单独给 void 弄一个没有 retValue 的特化。
|
15
lonewolfakela 2021-04-30 09:58:37 +08:00
@3dwelcome retCode 那里不同的人对于到底用“int retCode = 0”更好还是“int retCode{}”更好可能还会有些争论,但是代码段 2 里那个“Type retValue {}”,因为不知道 Type 的类型是啥,所以还真就只能这么写了……
|
16
greatbody 2021-04-30 10:14:08 +08:00
为啥现在人都说“小细节”而不说“细节”
以后是不是要说“特别微小细微的细节”? |
17
bestwaytowait 2021-04-30 10:17:18 +08:00
@greatbody 确实套娃了 =。= 哈哈哈哈
|
18
yazoox OP @leimao
3 不是“多余”的?我如果需要使用 type 为 void 的,我直接使用 EventResult<void>不就可以了么?干嘛要单独写一行,特别 definition 一下? |
19
yazoox OP @lonewolfakela
“因为成员 retValue 的类型不可能是 void” 为什么?模板的定义 Type retValue {}; 就是有可能是 void 啊? 尤其是,再单独使用代码段 3,和直接使用代码 2 EventResult<void>不是一样的么?单独定义,retValue 的类型就可以为 void 了? |
20
yazoox OP |
21
nicebird 2021-04-30 11:12:38 +08:00
1. {}构造
2. 和 1 一样 3. 偏特化,void 类型不要 retValue |
22
zwy100e72 2021-04-30 11:13:24 +08:00
没有 3 的情况下你是无法使用 EventResult<void> 的,因为无法定义一个 void 类型的成员变量。参见 https://godbolt.org/z/dxn1h4h5T
有 3 的情况下,EventResult<void> 的成员变量和 Base 一致,而其他类型的 EventResult<T> 有一个单独的 retValue 成员 https://godbolt.org/z/9TWfh1TGE |
23
lonewolfakela 2021-04-30 17:52:49 +08:00
@yazoox “为什么?模板的定义 Type retValue {}; 就是有可能是 void 啊?”
并不可能,因为变量的类型不能为 void 。 |