如何使用转发将RVALUE铸造为lvalue参考



当我不关心返回的int数据时,我试图使用超载函数将int引用传递给实用程序函数。为什么我需要使用T&而不是T作为模板参数?为什么我需要将i定义为RVALUE的中间功能?

class DataClass
{
};
template <typename T>
bool func(T& data, int& i) {
  i = 1;
  cout << "it worked!" << endl;
}
// I would like to remove this function
template <typename T>
bool func(T& data, int&& i) {
  return func(std::forward<T&>(data), std::forward<int&>(i));
}
template <typename T>
bool func(T& data) {
  // Why doesn't this line work?
  // return func(std::forward<T>(data), std::forward<int>(0));
  return func(std::forward<T&>(data), 0);
}
int main(int argc, char ** argv)
{
  DataClass d;
  func<DataClass>(d);
  return 0;
}

您根本不需要std::forward。除了第二个过载中的int&& i之外,您的参数都声明为非const lvalue参考,因此您不能将RVALUE传递给其中任何一个。在int&&过载中,如果要从rvalue函数调用lvalue函数,则只需命名参数 i,因为名称始终是lvalue。

template <typename T>
bool func(T& data, int& i) {
  i = 1;
  cout << "it worked!" << endl;
}
template <typename T>
bool func(T& data, int&& i) {
  return func(data, i);
}
template <typename T>
bool func(T& data) {
  return func(data, 0);
}

如果您想删除功能,请注意,实际上是int&有效地不同的是:它在技术上也将 i更改为1。在此之后忽略,因此呼叫者只能依靠func(T&, int&&)将消息打印给cout。并取一个不是lvalue的int ...只需 int

template <typename T>
bool func(T& data, int& i) {
  i = 1;
  cout << "it worked!" << endl;
}
template <typename T>
bool func(T& data, int i=0) {
  return func(data, i); // effect on i is ignored.
}
// Okay to pass a const int?
template <typename T>
bool func(T&, const volatile int&&) = delete;

第三个删除的模板保留了原始代码的一种行为,尽管尚不清楚您是否真的想要该行为。在功能

void test() {
    DataClass d;
    const int n = 5;
    func(d, n);
}

...原始代码将无法编译,因为const int LVALUE无法绑定到int&int&&。但是,将简单int参数的更改通过使n的副本成为普通的int参数,将允许此test编译。然后,即使您将n给予该功能,int i的更改也会被丢弃。删除的模板是const int LVALUE n的更好匹配,因此会导致test无法编译。如果您确实想要func(d, n)有效的行为,但对n没有影响,只需取出该删除的模板。

最新更新