2017-01-02 42 views
1

我试图创建将返回包含两种数据类型,其中第一种类型是始终不变的对的功能,但第二个是模板类型。这甚至有可能吗? (我也想知道我对std::forward使用的理解是否正确)。为了更好地展示我的问题,我将向您展示我的(不工作的)代码的简化示例。返回的std :: make_pair使用的std ::向前

这里是我的尝试:

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 - 以避免复制 - (根据斯科特迈耶斯的讲座,他解释std::forward是一个“有条件的移动”),取决于参数second是否为l值,我想通过second作为l值(让std::make_pairsecond的副本,创建对时)或者如果它是r值,我想通过“移动”的r值。

不幸的是我的代码不能正常工作。我想我一定误解了一些东西,但我不知道是什么,请你解释一下吗?

+1

“我的代码不能正常工作” - 什么不起作用?什么是错误信息? – Rakete1111

+1

@ Rakete1111的问题传递到FUNC -1-值参数 - 它是由'的std :: make_pair'作为参考推导出。问题解决了谢谢skypjack。 – mdjdrn1

+0

@ mdjdrn1无论如何Rakete1111是正确的,请注意并下次将错误消息与您的问题一起发布。它会帮助那些来帮忙的人。 ;-) – skypjack

回答

4

我怀疑你想要一个C++ 14-ISHstd::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>

+1

我已经测试了它'std :: decay_t'和'std :: remove_reference_t'并且完美地工作。在此之前,我没有注意到,当我通过函数l值时,它被推断为一个参考。十分感谢! – mdjdrn1

+1

@ mdjdrn1它们的目的不同,因此请查看文档以获取更多详细信息。而且......不客气。 ;-) – skypjack