当我不关心返回的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
没有影响,只需取出该删除的模板。