手动选择重载函数为右值或左值类型

manual select overloaded function for rvalue or lvalue type

本文关键字:类型 选择 重载 函数      更新时间:2023-10-16

我有重载的方法:

template<typename AnyType>
void AnyFunc(AnyType &t);
template<typename AnyType>
void AnyFunc(AnyType &&t);

我有一个调用者,它持有一个指针,想使用其中一个函数:

MyType* ptr=new MyType();
AnyFunc(*ptr);

最后一行遇到编译错误:AnyFunc 的重载不明确

如何选择我需要的功能?简单的情况是使用:

AnyFunc(std::move(*ptr)); 

选择void AnyFunc(AnyType &&t);但这不是我想要的。我需要void AnyFunc(AnyType &t);方法。

任何时候你都有T&& v(其中T是一个模板参数),你就有一个所谓的通用引用。它不仅与右值绑定,与左值绑定。这是一个贪婪的模板。它会拿走它能得到的任何东西,也不会回馈任何东西。

当涉及贪婪的模板时,重载是一个主意,除非您确切地知道自己在做什么。

使用通用引用,通常不需要特殊情况的左值与右值。只需std::forward<T>(v)参数,值类别就会被传播。

不需要修复。您的代码符合 C++11。这些情况的标准规定,非通用参考模板"更专业",将优先。

因此,您的调用应选择第一个模板。如果删除第一个模板,它将采用第二个模板。它类似于这个

// "universal" with respect to const qualification
template<typename T>
void f(T &);
template<typename T>
void f(const T&);

现在,这将调用第二个模板实例,因为虽然两个实例都具有const int&作为参数类型,但第二个实例与更专业的函数模板相关联。

const int a = 0;
f(a);

在你的情况下也是如此。请注意,它是"完整的",因为它适用于常量和左值/右值的所有组合

  • 常量左值。两者都有const U&作为参数,但T&更专业,所以它通过部分排序来获取。
  • 非常量左值,你的案子。T&U&作为参数,T&&的也有U&作为参数,但T&的更专业,所以通过部分排序。
  • 常量右值T&一个const U&作为参数,T&&一个const U&&作为参数。右值引用是将右值绑定到左值引用的首选。因此,T&&通过过载分辨率来获取。
  • 非常量右值T&U&作为参数。非常量左值引用不能绑定到右值。因此,具有类型U&&T&&通过过载分辨率来选择。