Skip to content

decltype(auto) 的描述存在错误 #88

@frederick-vs-ja

Description

@frederick-vs-ja

cppguidebook/docs/auto.md

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions