使用decltype和auto推导const(return)类型

时间:2018-06-05 21:11:03

标签: 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'

更多演绎变体(see at compiler explorer)的示例。

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();
}

为什么iDT_fromVar的常量与i_fromVar不同? (decltype(auto) vs auto for vars)

为什么iDT_fromVar的常量与iDT不同? (来自上面的问题)

i_fromVari没有时,为什么iDTiA / iDT_fromVar / iDT具有相同的常量?

1 个答案:

答案 0 :(得分:3)

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

C ++ 17中的相关子句是[expr] / 6:

  

如果prvalue最初具有类型“cv T”,其中T是cv非限定的非类非数组类型,则表达式的类型将调整为{{1在进行任何进一步分析之前。

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