2017-01-02 5 views
1

2つのデータ型を含むペアを返す関数を作成しようとしています。最初の型は常に同じですが、2つ目はテンプレート型です。それも可能ですか? (std::forwardの使用についての私の理解が正しいかどうかも疑問です)。私の問題をよりよく実証するために、私の(動作していない)コードのサンプルを簡略化して表示します。std :: make_pairを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をコピーするのを避けるために - そして、がl-valueだったかどうかに応じて、std::forwardを "条件付き移動"として説明したScott Meyersの講義に従います。secondをl-値として渡したい場合はstd::make_pairsecondのコピー、ペアを作成するとき)、またはr値だった場合は、「移動した」r値を渡したいと思います。

残念ながら私のコードは機能しません。私は何か誤解しているに違いないと思っていますが、何が分かりませんか、私に説明してください。

+1

"私のコードは機能しません" - 何がうまくいかない?エラーメッセージとは何ですか? – Rakete1111

+1

@ Rakete1111問題はfuncのl-value引数に渡されました。これは 'std :: make_pair'を参照として導き出されました。 skypjackのおかげで問題は解決しました。 – mdjdrn1

+0

@ mdjdrn1とにかくRakete1111が正しいです、次回あなたの質問に沿ってエラーメッセージを投稿してください。それは助けに来る人々を助けるでしょう。 ;-) – skypjack

答えて

4

私はあなたがstd::decay_tまたはあなたの宣言でstd::remove_reference_tC++ 14-っぽいたい疑う:

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)); 
} 

このようにして、左辺参照または右辺値参照Xfuncの実際のパラメータとして使用している場合でも、std::pairはを使用しますタイプとして。


あなたがstd::pairの種類としてXへの参照を使用することはできません。
のは、次の例を考えてみましょう:

この場合
#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); 
} 

Xint &と推定されます。したがって、返される型は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'の両方をテストしており、完全に動作します。その前に私は気づいていませんでした。私がfuncの値を渡していたとき、それは参考として推測されました。本当にありがとう! – mdjdrn1

+1

@ mdjdrn1彼らは目的が異なるので、詳細についてはドキュメントを見てください。そして...あなたは大歓迎です。 ;-) – skypjack

関連する問題