C++ 使用decltype和auto推断const(return)类型

C++ 使用decltype和auto推断const(return)类型,c++,C++,为什么decltype从变量而不是从函数推导出const const int f() { const int i = 1; return i; } decltype(auto) i_fromFunc = f(); // i_fromFunc is of type 'int' const int i = 1; decltype(auto) i_fromVar = i; // i_fromVar is of type 'const int' 示例包含更多演绎变量() 为什么iD

为什么
decltype
从变量而不是从函数推导出
const

const int f()
{
    const int i = 1;
    return i;
}
decltype(auto) i_fromFunc = f(); // i_fromFunc is of type 'int'

const int i = 1;
decltype(auto) i_fromVar = i; // i_fromVar is of type 'const int'

示例包含更多演绎变量()

为什么
iDT\u fromVar
的常量不同于
i\u fromVar
?(
decltype(auto)
vs
auto
用于VAR)

为什么
iDT\u fromVar
的常数不同于
iDT
?(上面的问题)


为什么
i\u fromVar
i
/
iDT
/
iA
具有相同的常量,而
i\u fromVar
iDT
没有相同的常量?

没有非类类型的
常量。函数
const int f()
基本上等同于
int f()

C++17中的相关条款为[expr]/6:

如果prvalue最初的类型为“cv
T
”,其中
T
是cv不合格的非类、非数组类型,则在进行任何进一步分析之前,表达式的类型将调整为
T


如果尝试使用类类型而不是返回类型为
int
的类似代码,您将看到不同的行为。

没有非类类型的
const
pr值。函数
const int f()
基本上等同于
int f()

C++17中的相关条款为[expr]/6:

如果prvalue最初的类型为“cv
T
”,其中
T
是cv不合格的非类、非数组类型,则在进行任何进一步分析之前,表达式的类型将调整为
T


如果使用类类型而不是
int
作为返回类型尝试类似的代码,您将看到不同的行为。

IIRC,编译器将丢弃函数声明中的
const
<代码>常量int foo()
int foo()
.IIRC相同,编译器将丢弃函数声明中的
const
<代码>常量int foo()与
int foo()
相同。感谢您提及prvalue。因此,在进一步分析之前,似乎意味着在对
decltype
auto
进行评估之前。在cppreference for Value categories(值类别)中,函数调用或强制转换表达式可能会导致非类cv限定类型的prvalue,但cv限定符会立即删除,从而导致相同的结果。感谢您提及prvalue。因此,在进一步分析之前,似乎意味着在对
decltype
auto
进行评估之前。在cppreference中,对于值类别,函数调用或强制转换表达式可能会产生非类cv限定类型的prvalue,但cv限定符会立即被删除,从而产生相同的结果。
const int func()
{
    const int i = 1;
    return i;
}

decltype(auto) funcDecltype()
{
    const int i = 1;
    return i;        
}

auto funcAuto()
{
    const int i = 1;
    return i;
}

void DeduceFromFunc()
{
    decltype(auto) i = func(); // i is of type 'int', similar to auto i = func()
    i = 2;
    decltype(auto) iDT = funcDecltype(); // iDT is of type 'int', similar to auto iDT = funcDecltype()
    iDT = 2;
    decltype(auto) iA = funcAuto(); // iA is of type 'int', similar to auto iA = funcAuto().
    iA = 2;

    // For the sake of completeness:

    const auto ci = func(); // const int
    //ci = 2; // Not mutable.

    //auto& iRef = func(); // non const lvalue of 'int&' can't bind to rvalue of 'int'
    const auto& ciRef = func(); // const int &
    //ciRef = 2; // Not mutable.

    auto&& iRV = func(); // int &&
    iRV = 2;
    const auto&& ciRV = func(); // const int &&
    //ciRV = 2; // Not mutable.
}

const int gi = 1;

void DeduceFromVar()
{
    auto i_fromVar = gi; // i_fromVar is of type 'int'.
    i_fromVar = 2;
    decltype(auto) iDT_fromVar = gi; // iDT_fromVar is of type 'const int'
    //iDT = 2; // Not mutable.

    // For the sake of completeness:
    auto& iRef = gi; // reference to const int
    //iRef = 2; // Not mutable.
    auto&& iRVRef = gi; // rvalue ref to const int
    //iRVRef = 2; // Not mutable.
}

int main()
{
    DeduceFromFunc();
    DeduceFromVar();
}