-
Notifications
You must be signed in to change notification settings - Fork 68
Open
Description
Lines 381 to 399 in a6b0691
返回类型声明为 `decltype(auto)` 的效果等价于把返回类型替换为 `decltype((返回表达式))`: | |
```cpp | |
int i; | |
decltype(auto) func() { | |
return i; | |
} | |
// 等价于: | |
decltype((i)) func() { | |
return i; | |
} | |
// 等价于: | |
int &func() { | |
return i; | |
} | |
``` | |
> {{ icon.warn }} 注意 `decltype(i)` 是 `int` 而 `decltype((i))` 是 `int &`。这是因为 `decltype` 实际上有两个版本!当 `decltype` 中的内容只是单独的一个标识符(变量名)时,会得到变量定义时的类型;而当 `decltype` 中的内容不是单纯的变量名,而是一个复杂的表达式时,就会进入 `decltype` 的第二个版本:表达式版,会求表达式的类型,例如当变量为 `int` 时,表达式 `(i)` 的类型是左值引用,`int &`,而变量本身 `i` 的类型则是 `int`。此处加上 `()` 就是为了让 `decltype` 被迫进入“表达式”的那个版本,`decltype(auto)` 遵循的也是“表达式”这个版本的结果。 |
实际上在返回类型推导中, decltype(auto)
并不会始终把 return
的操作数始终当成表达式,而是仍然区分变量名及其他表达式。Godbolt link
template<class, class>
constexpr bool my_is_same_v = false;
template<class T>
constexpr bool my_is_same_v<T, T> = true;
int i;
decltype(auto) f1() { return i; }
decltype(auto) f2() { return (i); }
static_assert(my_is_same_v<decltype(f1), int()>);
static_assert(my_is_same_v<decltype(f2), int&()>);
Metadata
Metadata
Assignees
Labels
No labels