当我不在乎返回的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;
}
答案 0 :(得分:1)
这里完全不需要std::forward
。除了第二个重载中的int&& i
之外,您的参数都声明为非常量左值引用,因此您无法将右值传递给其中的任何一个。并且在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
。而要使用不是左值的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&
或int&&
上,因此原始代码将无法编译。但是,只需将参数int
的副本更改为简单的test
参数,对参数n
的更改将允许此int
进行编译。这样,即使您将int i
赋予了功能,对n
的更改也将被放弃。删除的模板与const int
左值n
更好地匹配,因此将导致test
无法编译。如果您确实希望func(d, n)
有效但对n
没有影响的行为,只需取出删除的模板即可。