2016-11-27 7 views
3

私はC++での転送の概念を理解しようとしており、以下のコードをvaradicテンプレートのこの機能を理解するために書いています。私は、エラーの下に取得していたコードを実行しながらC++で完璧な転送が機能しない

#include<utility> 
#include<string> 
#include<tuple> 
#include<sstream> 

template<typename... Args> struct Helper_Class 
{ 
    std::tuple<Args...> argTuple; 
    Helper_Class(Args&&... args): 
        argTuple(std::make_tuple(std::forward<Args>(args)...)) 
    {} 
}; 

template<typename... Args> std::ostream& 
operator<< (std::ostream& os,Helper_Class<Args...> obj) 
{ 
    return os; 
} 

template<typename...Args> 
Helper_Class< Args...> 
Print(Args&&... args) 
{ 
    return Helper_Class<Args...>(std::forward<Args>(args)...); 
} 

template <typename... Ts> 
void test(Ts &&...params) { 
    std::stringstream s; 
    s <<Print(std::forward<Ts>(params)...); 
} 

int main() 
{ 
    test(1,2,"foo", 'x'); 
} 

しかし、私は完璧な転送を実行しようとしていた場合

error: no matching function for call to ‘std::tuple<int, int, const char (&)[4], char>::tuple(std::tuple<int, int, const char*, char>)’ 
     argTuple(std::make_tuple(std::forward<Args>(args)...)) 

私は何を理解していないですがある(タイプは関数呼び出しの間で変更すべきではありませんを意味します)どうしてタイプを変更しようとしているのですか?

私がこのコンセプトを初めて学んでいるとき、これが非常に基本的なものであれば、ごめんなさい。

アップデート1:上に掲載 継続質問:Question

答えて

5
template <typename... Ts> 
void test(Ts &&...params) { 
    std::stringstream s; 
    s <<Print(std::forward<Ts>(params)...); 
} 

あなたがここに開始するつもりです。 Printのテンプレートパラメータはstd::forwardから出てきます。そのようなものとして、それらはすでに左値/右値参照を転送されます。これは、Printテンプレートのパラメータとして、ここで押しつけるものです。その後

template<typename...Args> 
Helper_Class< Args...> 
Print(Args&&... args) 

これは、今ら、右辺値参照を左辺値参照を含むタプルを宣言しようとするこれらの型を使用します。これは、Helper_ClassArgs...を転送しようとしています。それはうまく動作しません。

あなたはneed to decayこれらの吸盤:

template<typename...Args> 
Helper_Class< typename std::decay<Args>::type...> 
Print(Args&&... args) 
{ 
    return Helper_Class<typename std::decay<Args>::type...>(std::forward<Args>(args)...); 
} 

か、のは、いくつかの視覚的な混乱をクリーンアップするC++ 14を使用してみましょう...

template<typename...Args> 
auto Print(Args&&... args) 
{ 
    return Helper_Class<typename std::decay<Args>::type...>(std::forward<Args>(args)...); 
} 

この今、GCC 6.2で、私のためにコンパイル。 1。

P.S.これはちょうど「基本的な」ものではありません...

+0

'decay_t'を使うこともできますので、' typename'や ':: type'は不要です。 – 0x499602D2

+0

これは、lvaluesではなくrvaluesを受け入れることができます。 – 0x499602D2

関連する問題