2017-06-13 12 views
4

Variadicテンプレートは、再帰的な操作を行う上で本当に便利です。この場合、私は繰り返し呼び出す必要がないので、それぞれの再帰呼び出しを2つの引数で操作したいと思います。私は書くことができ、この達成するために:Variadicテンプレートの引数群を渡す

f() {} 

template<typename M, 
     typename N, 
     typename... Rest> 
f(M arg1, N arg2, Rest... rest) 
{ 
    doStuff(arg1, arg2); 
    f(rest); 
} 

をそれから私は、このようなとしてこれを呼び出します。しかし

f(arg1a, arg1b, 
    arg2a, arg2b, 
    arg3a, arg3b); 

、コールがそのようにきれいにフォーマットされ、すべての引数が1行上にあるされていない場合、または列が間違った点で分割されても、それはかなり読めなくなります。特にそのような場合は、数十人程度のペアが含まれている可能性があります。これは主に初期化子リストとして失敗しているようだ

f({arg1a, arg1b}, 
    {arg2a, arg2b}, 
    {arg3a, arg3b}); 

取得していません:。私は、このように呼ばれるように持っている機能を希望に渡されるペアのパラメータパックを必要とすることによってこの問題を解決しようとしましたペアに推論する私は引数の各セットでmake_pairを呼び出すことができますが、それは別の可読性問題で可読性の問題を解決するだけです。このような呼び出し構文を使用する方法はありますか?引数はペア間またはペア内で同じではありません。

+1

'arg1a'、' arg1b'、 'arg2a'、' arg2b'、...はすべて異なるタイプですか? – NathanOliver

+0

うん。私の場合、それらはすべてQt接続のメンバー関数ポインタですが、各関数は異なる引数を取ることができます – TheLoneMilkMan

+2

OK。 AFAIKには、これを行う方法がありません。 '{arg1a、arg1b}'には型がないので、推論できません。 – NathanOliver

答えて

1

これは驚くようですが、私が見つけた最良の解決策は、実際にはバリデーションをまったく使用しない「過去からの爆発」です。

struct F { 
    template <class M, class N> 
    F& operator()(M arg1, N arg2) { 
     doStuff(arg1, arg2); 
     return *this; 
    } 
}; 

F{} (arg1a, arg1b) 
    (arg2a, arg2b); 

など。しかし、私はclang-formatがこれをきれいにフォーマットしていないことにも気付くでしょう。だから私はやや違うことをもう一度やりました。

2

申し訳ありません。ブレースリストからユーザー定義型への暗黙的な型変換です。可能な唯一のコンバージョンはstd::initializer_listですが、同じタイプまたはコンバチブルタイプの場合にのみ行うことができます。これにより

は私が

もちろん
template <typename M, typename N> 
void doStuff(M&&, N&&) {} 

template <typename M, typename N> 
struct MyRepeater; 

template <typename M, typename N> 
MyRepeater<M, N> f(M&& one, N&& two); 

template <typename M, typename N> 
struct MyRepeater { 
    template <typename I, typename J> 
    MyRepeater<I, J> operator()(I&& one, J&& two) const { 
    return f(std::forward<I>(one), std::forward<J>(two)); 
    } 
}; 

template <typename M, typename N> 
MyRepeater<M, N> f(M&& one, N&& two) { 
    doStuff(one, two); 
    return MyRepeater<M, N>(); 
} 

int main() { 
    f(Foo1(), Foo2())(Bar1(), Bar2())(Bar2(), Foo1()); 
} 

、マイナス面だけ読みやすくするために、あなたは、2つの私の意見では(いくつかの余分なコードを書いていることで、可能性として、これを提供するであろう、と述べ、そうではありません悪い動機)。

関連する問題