函数调用的 Decltype 丢弃 const 限定符

问题描述 投票:0回答:1

考虑一个函数

template <typename T>
    const T&& foo();

当我尝试测试它时,我发现了我不明白的结果。输出为 0.

#include <iostream>

class C{};

template <typename T>
    const T&& foo();

int main() {
    std::cout << std::is_same_v<decltype(foo<C&&>()), const C&&>;
    return 0;
}

decltype 不应该保留 const 限定符吗?在我看来,它应该像

T-> C&&
,所以通过引用折叠规则返回类型是
const C&&
,结果的decltype是
const C&&

另外,这条线

std::cout << std::is_same_v<decltype(foo<int>()), const int&&> << '\n';

按预期打印 1.

有人能帮我找出正确的工作逻辑吗?

我发现当 decltype 应用于非类纯右值时,cv 限定符被丢弃。但事实并非如此,因为

foo<int&&>()
的值类别是xvalue,这也不适用于类类型
C

c++ templates c++17 return-value decltype
1个回答
0
投票

不应该 decltype 保留 const 限定符?

是的,这里也是。

foo<C&&>()
的返回类型确实是
C&&
,而不是
const C&&

在我看来应该是T->C&&,所以通过引用折叠规则返回类型是const C&&,结果的decltype是const C&&

不,您首先将

const
应用于
T
,然后是
&&

const T&&
的意思是“rvalue reference to (
const T
)
”。它并不意味着“
const
(对
T
的右值引用)
”。

const
应用在顶层
T
。这意味着如果
T
C&&
,您正在尝试对引用进行
const
限定,但在 C++ 中没有
const
限定的引用。所以语言规则说
const
在尝试通过这样的构造
const
-限定引用时被忽略。


std::cout << std::is_same_v << '\n';

在这里,您将

const
应用到
int
上,从而得到
const int
,然后在顶部添加
&&
。所以你得到
const int&&
.

我发现当 decltype 应用于非类纯右值时,cv 限定符被丢弃。

它们在非类类型纯右值表达式上被丢弃,但在函数本身的返回类型上不被丢弃。如果一个函数被声明为返回

const T
并且您用
int
代替
T
,那么该函数的返回类型为
const int
,但是对该函数的调用是一个类型为
int
.

的纯右值表达式

但事实并非如此,因为 foo() 的值类别是 xvalue,这也不适用于类类型 C。

对,没错。这条特殊规则在这里无关紧要。

decltype
确实忠实地再现了声明的返回类型。

© www.soinside.com 2019 - 2024. All rights reserved.