使用std :: forward

时间:2017-01-02 20:57:40

标签: c++ c++11

我正在尝试创建一个函数,它将返回包含两种数据类型的对,其中第一种类型总是相同,但第二种是模板类型。这甚至可能吗? (我也想知道我对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值。

不幸的是我的代码不起作用。我想我一定是误解了什么,但我不知道是什么,你能解释一下,拜托吗?

1 个答案:

答案 0 :(得分:4)

我怀疑你的宣言中需要 C ++ 14-ish std::decay_tstd::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>