2011-12-20 5 views
10

は、私が2つのstruct Sがあるとオブジェクトのメンバーを転送しますまたはX&&~f()パーフェクト

template <typename T> 
void g(T&& t) { 
    if (is_lvalue_reference<T>::value) { 
    f(t.x); 
    } else { 
    f(move(t.x)); 
    } 
} 

上記のコードは私の意図を示していますが、パラメータの数が増えるにつれてスケーラビリティがあまり高くありません。完璧なフォワーディングを実現し、スケーラブルにする方法はありますか?私はよく分からないが、

+0

私が変える 'is_lvalue_reference :: [値] is_lvalue_reference'へを::(t)を考えます)> :: value'はあなたが望むセマンティクスを持っていますが、私はあなたが望むセマンティクスは疑問だと思います... – ildjarn

+0

(ひどい答えをお送りください。)私はそれが縮尺されていない理由はデザインがまずは疑わしい。サブオブジェクトを「移動」するのはどういう意味ですか?これは主な目的をどの状態で残していますか?これを書く簡単な方法があったとしても、構造化されていないコードのように見えます。 –

答えて

15
template <typename T> 
void g(T&& t) { 
    f(std::forward<T>(t).x); 
} 
+1

私によく見えますhttp://ideone.com/Edf4o –

+0

もっと良い解決策ですが、なぜそれは正確に機能しますか? 'rvalue.foo'はrvalueなので、 – Pubby

+0

@Pubbyです。私はなぜそれが意味をなさないのだろうと考えています(コンテナの寿命が短く、価値がある場合、含まれているオブジェクトもそのプロパティを共有しています)。しかし、私は哲学に精通しておらず、その根拠も知らないのでそれについて何も言えません。 –

3

私は、これがうまくいくと思う:

template<class T, class M> 
struct mforward { 
    using type = M&&; 
}; 
template<class T, class M> 
struct mforward<T&, M> { 
    using type = M&; 
}; 

template <typename T> 
void g(T&& t) { 
    f(std::forward<typename mforward<T, decltype(t.x)>::type>(t.x)); 
} 
+2

+1 libC++のほぼ正確な問題を解決しなければなりませんでした。私が思いついた解決策はPubby'sと非常に似ていました。 'T 'のl/r-valuenessを' M'に「適用」したいだけでなく、 'M'に' T'のCV資格を適用したいと考えました。そして、私はデータメンバー以外のアプリケーションを見つけました。不思議なことに、私は '__apply_cv'と呼んでいました。それはオープンソースのコードです:http://libcxx.llvm.org/ –

+0

@Howardは私の答えを見てください。それとも、私は何かが恋しいですか? –

+0

また、cv資格について話すことは、私にこの答えの瑕疵について考えるようになります。 'decltype(t.x)'は 'x'の宣言された型だけを与えます。 'T'が' const'で 'x'が' int a'と宣言された場合、フォワードは 'int&'/'int &&'として物事を転送しようとします。 'typename remove_reference :: type'のように、' t'の定数も考慮に入れる必要があります。これは 'mutable'メンバーも考慮に入れていますが、私はどのような動きが哲学的には' const'オブジェクトの変更可能なメンバーに何を意味するのか分かりません。 –

関連する問題