我正在尝试创建一个函数,它将返回包含两种数据类型的对,其中第一种类型总是相同,但第二种是模板类型。这甚至可能吗? (我也想知道我对std::forward
用法的理解是否正确)。为了更好地演示我的问题,我将向您展示我的(不工作)代码的简化示例。
这是我试过的:
template <class X>
std::pair<int, X> func(X&& second)
{
int first = 1;
return std::make_pair(std::move(first), std::forward<X>(second));
}
在内部函数中,我创建变量first
,然后我想返回对。在这里,我移动first
- 以避免复制 - 并且(根据Scott Meyers的讲座,他将std::forward
解释为“条件移动”),这取决于参数second
是否是l值我想要将second
作为l值传递(让std::make_pair
复制second
,创建对时)或者如果是r值我想传递“移动”的r值。
不幸的是我的代码不起作用。我想我一定是误解了什么,但我不知道是什么,你能解释一下,拜托吗?
答案 0 :(得分:4)
我怀疑你的宣言中需要 C ++ 14-ish std::decay_t
或std::remove_reference_t
:
template <class X>
std::pair<int, std::decay_t<X>> func(X&& second) {
int first = 1;
return std::make_pair(std::move(first), std::forward<X>(second));
}
或者C ++ 11,更详细,但是等效版本:
template <class X>
std::pair<int, typename std::decay<X>::type> func(X&& second) {
int first = 1;
return std::make_pair(std::move(first), std::forward<X>(second));
}
这样,无论您使用左值引用还是X
的右值引用作为func
的实际参数,您的std::pair
都会使用X
一种类型。
请注意,您无法使用X
的引用作为std::pair
的类型
让我们考虑以下示例:
#include<utility>
template <class X>
std::pair<int, X> func(X&& second) {
int first = 1;
return std::make_pair(std::move(first), std::forward<X>(second));
}
int main() {
int i = 42;
func(i);
}
在这种情况下,X
推断为int &
。因此返回类型为std::pair<int, int &>
,这是不允许的,也不会编译。
以下将编译:
template <class X>
std::pair<int, std::remove_reference_t<X>> func(X&& second) {
int first = 1;
return std::make_pair(std::move(first), std::forward<X>(second));
}
这是因为X
仍被推断为int &
,但现在将返回类型调整为std::pair<int, int>
。