2016-11-16 5 views
2

を(値)をパック:拡張パラメータは再帰で通常の方法を使用してパックを拡大しようとしているテンプレート引数から

template<bool first> int func1(int value = 0) { 
    return some_func(first, value); 
} 

template<bool first, bool... args> int func1(int value = 0) { 
    return func1<args...>(some_func(first, value)); 
} 

は、コンパイル時の再帰の最後のステップで、関数func1の呼び出しが曖昧で、 第一候補私の場合は最初の関数である、それは明らかだ、いくつかの具体的な専門:[偽=ブール最初付き]

int型の関数func1(int型)

ですが、2番目は

です。int func1(int)[bool first = false;ブール... args = {}]

あなたはそれも正しいことがわかります - 最初のものの後の引数の空集合。 これを防ぐにはどうすればよいですか?

答えて

4

は、明示的secondパラメータを追加することにより、再帰的なケースからベースケースを明確ありがとう:

template<bool first> int func1(int value = 0) { 
    return some_func(first, value); 
} 

template<bool first, bool second, bool... args> int func1(int value = 0) { 
    return func1<second, args...>(some_func(first, value)); 
} 

Wandbox example

+0

は、この構造は一つだけの関数にすることができるようですconstexpr ifを使うif – amigo421

0

を最後に、私は再帰を使用しませんでしたが、以下の唯一のコードです。

(実際にはstd ::配列が必要とされていませんが、私の観点から、より便利に、 エキスパンドがあまりにもC-ような配列を使用してアーカイブすることができます)

template <bool... args> unsigned long func1() { 
    std::array<bool, sizeof...(args)> ar{args...}; 

    // the piece specific for my task 
    std::bitset<sizeof...(args)> bs; 
    for(std::size_t i = 0; i < ar.size(); ++i) { 
     bs[i] = ar[i]; 
    } 

    // ... processing ... 
    return bs.to_ulong(); 
}