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

ant*_*_rh 2 c++ rvalue overload-resolution

我有以下功能:

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

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

void* const func2()
{
    return nullptr;
}
Run Code Online (Sandbox Code Playgroud)

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

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

func(func2());
Run Code Online (Sandbox Code Playgroud)

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

mutable
Run Code Online (Sandbox Code Playgroud)

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

然而,当void*我将 const 传递struct给函数时,这不会发生:

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;
}
Run Code Online (Sandbox Code Playgroud)

结果是:

const
Run Code Online (Sandbox Code Playgroud)

您可以在coliru查看

constvoid*和 const 有什么区别struct

有没有办法使重载特别采用 const 值?

Sto*_*ica 6

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

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

[表达式类型]

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

类类型纯右值保留其 cv 限定,但不保留void* const纯右值。因此,重载解析发生在void*纯纯右值上,这解释了您在选择右值重载时观察到的行为。

本段适用的类型是那些其值被程序实际访问的“基本”类型。所以这种类型的纯右值确实是一个“纯”的、短暂的值,并且不能被修改。

  • @anton_rh - 如果你非常希望它是 const 的话,你可以采用 `void* const &amp;&amp;` 。但是您不能影响输入重载解析的表达式的类型。或者我们可以不犯傻,直接按值取一个“void*”。 (2认同)