-2

当我不关心返回的 int 数据时,我正在尝试使用重载函数来隐藏将 int 引用传递给实用函数。为什么我需要使用它T&而不是T作为模板参数?为什么我需要定义i为右值的中间函数?

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;
}
4

1 回答 1

2

你这里根本不需要std::forward。除了int&& i在第二个重载中,您的参数都声明为非常量左值引用,因此您不能将右值传递给它们中的任何一个。而在int&&重载中,如果你想从右值函数调用左值函数,你可以只命名参数i,因为名称始终是左值。

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. 并取一个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左值不能绑定到int&or int&&。但是对参数的更改int将允许它test通过复制n作为普通int参数来编译。int i然后,即使您提供n了该功能,对它的更改也会被丢弃。删除的模板更适合const int左值n,因此会导致test编译失败。如果您确实想要func(d, n)有效但对 没有影响的行为n,只需取出已删除的模板。

于 2019-05-13T17:36:24.773 回答