传递 const int* 和 int* 时调用不同版本的重载函数 (const int* const&/&&)
A different version of an overloaded function(const int* const&/&&) gets called when passing const int* and int*
我在我的代码中遇到了一个错误,其中调用了错误的重载函数。
问题归结为:
void func(const int* const& ptr){
std::cout << "LValue reference\n";
}
void func(const int* const&& ptr){
std::cout << "RValue reference\n";
}
int main(){
const int* ptr;
func(ptr);
return 0;
}
上面的代码按预期工作,它打印 LValue reference
。
但是,当我将 const int* ptr
更改为 int* ptr
时,程序会打印 RValue reference
。这对我来说很奇怪,因为我向它传递了一个已确认的 LValue。
这让我相信某种隐式转换正在发生,将它变成了 RValue。我确实用 godbolt compiler explorer 研究过它,乍一看会证实我的怀疑,但我对汇编一无所知,所以我不能肯定。
所以问题是:这里发生了什么?
int*
与 const int*
不是同一类型。由于它们不是同一类型,因此必须进行转换,因为您不能将引用绑定到不同的类型,然后它被声明为引用(处理派生对象时除外)。
这意味着 int*
用于创建一个临时 const int*
并且这个临时指针是一个右值。由于它是右值,因此将选择右值引用重载。
我在我的代码中遇到了一个错误,其中调用了错误的重载函数。
问题归结为:
void func(const int* const& ptr){
std::cout << "LValue reference\n";
}
void func(const int* const&& ptr){
std::cout << "RValue reference\n";
}
int main(){
const int* ptr;
func(ptr);
return 0;
}
上面的代码按预期工作,它打印 LValue reference
。
但是,当我将 const int* ptr
更改为 int* ptr
时,程序会打印 RValue reference
。这对我来说很奇怪,因为我向它传递了一个已确认的 LValue。
这让我相信某种隐式转换正在发生,将它变成了 RValue。我确实用 godbolt compiler explorer 研究过它,乍一看会证实我的怀疑,但我对汇编一无所知,所以我不能肯定。
所以问题是:这里发生了什么?
int*
与 const int*
不是同一类型。由于它们不是同一类型,因此必须进行转换,因为您不能将引用绑定到不同的类型,然后它被声明为引用(处理派生对象时除外)。
这意味着 int*
用于创建一个临时 const int*
并且这个临时指针是一个右值。由于它是右值,因此将选择右值引用重载。