【问题标题】:Why is const temporary bound to rvalue reference parameter?为什么 const 临时绑定到右值引用参数?
【发布时间】:2021-09-09 14:51:39
【问题描述】:

我有以下功能:

void func(void * const &ptr)
{
    std::cerr << "const" << std::endl;
}

void func(void *      &&ptr)
{
    std::cerr << "mutable" << std::endl;
}

void* const func2()
{
    return nullptr;
}

一个重载采用 const 引用参数,另一个采用可变右值引用。还有一个返回 const 值的函数。

当我将该 const 临时值传递给函数时:

func(func2());

我希望选择 const 重载。但相反,我得到:

mutable

这怎么可能?为什么 const 返回值绑定到非 const 右值引用参数?

但是,当我将 const struct 传递给函数而不是 void* 时,不会发生这种情况:

struct A
{
};

void func(A const &a)
{
    std::cerr << "const" << std::endl;
}

void func(A      &&a)
{
    std::cerr << "mutable" << std::endl;
}

A const func3()
{
    return A(); 
}

int main()
{
    func(func3());
    return 0;
}

结果是:

const

您可以在coliru 上查看。

const void* 和 const struct 有什么区别?

有没有办法使重载专门采用 const 值?

【问题讨论】:

    标签: c++ rvalue overload-resolution


    【解决方案1】:

    为什么 const 临时绑定到右值引用参数?

    因为在重载决议发生时它不是 const。

    [expr.type]

    2 如果纯右值最初的类型为“cv T”,其中 T 是无 cv 限定的非类、非数组类型,则表达式的类型会在任何进一步分析之前调整为 T。

    类类型纯右值保留其 cv 限定,但不保留 void* const 纯右值。因此,重载解决方案使用普通的void* prvalue,它解释了您在选择右值重载时观察到的行为。

    本段适用的类型是那些“基本”类型,其值实际上由程序访问。所以这种类型的prvalue确实是一个“纯”的、短暂的值,已经不能修改了。

    【讨论】:

    • 有没有办法让重载专门采用 const 值?
    • @anton_rh - 如果你希望它是 const 这么多,你可以使用 void* const &amp;&amp;。但是你不能影响你输入重载决议的表达式的类型。或者我们不能傻,直接按值取void*
    • 不,void* const &amp;&amp; 没有帮助。
    • @anton_rh - 如果你这么说。不管怎样,这就是答案。
    猜你喜欢
    • 2013-07-04
    • 2017-04-15
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    • 2017-04-13
    • 1970-01-01
    相关资源
    最近更新 更多