2015-11-13 7 views
5

ここでは、コンパイルエラーをトリガ最小限の例です:なぜこの可変的なテンプレートパラメータの置換に失敗しますか? (パックの前に固定引数)

#include <utility> 
void foo(int, double, int) 
{} 

template <class... Args> 
void post_forwarder(void(*fun)(Args..., int), Args&&... aArgs) 
{ 
    fun(std::forward<Args>(aArgs)..., 5); 
} 

int main() 
{ 
    post_forwarder(foo, 6, 6.1); // Compilation error on instantiation 
    return 0; 
} 

私は問題は可変引数テンプレートパラメータが固定int型のパラメータの前に関数型で展開されているという事実に関係している疑いがありますしかし、それが事実なら、私はそれのための良い根拠を見つけることができません。

クラン3.6で報告されるエラーは次のとおりです。

error: no matching function for call to 'post_forwarder' 
note: candidate template ignored: failed template argument deduction 
+1

あなたはエラーを投稿できますか?それは役に立つだろう。 – lodo

+1

さて、 'Args && ... 'と推測された' Args ... '関数ポインタへの転送は良い計画ではありません。あなたがそれを知っていることを確認するだけです。 – Yakk

+0

@ Yakk私は、あなたが上げようとしているポイントについて、もっと詳しく述べることができることを認めなければなりません:) –

答えて

7

引数を。通常の解決策は、控除できないようにするためです。

template <typename T> 
struct identity { 
    using type = T; 
}; 

template <class... Args> 
void post_forwarder(void(*fun)(typename identity<Args>::type..., int), Args&&... aArgs) 
{ 
    fun(std::forward<Args>(aArgs)..., 5); 
} 
+0

技術的に言えば、最初の 'Args ...'はすでに推論されていないコンテキストです。 –

+1

@ T.C。ええ、今は**超**非推論の文脈です。 [また、私は完全な説明がありません] – Barry

+0

http://stackoverflow.com/questions/26885239/whats-the-point-of-boostmplidentityttype-here。 sidenoteとして、私は本当に 'dont_deduce'のような文脈で' identity 'のエイリアスを好むでしょう。なぜなら、少なくとも私がその仕組みを理解していなくても、その目的が分かっています。 –

0

編集:書き直し答え:Args..., intArgs...を推測することはできません

形。

+0

本当ですか? 'fun'シグネチャには明示的な最後の' int'がありますが、最初の2つのパラメータに 'Args ...'を制限することが期待されます。 –

1

これは動作します:パラメータパックを演繹する最後でなければならないこと、一般的なルールの

template <class... Args> 
void post_forwarder(void(*fun)(Args..., int), Args&&... aArgs) 
          // ^^^^^^^ 

:控除はここに失敗し

template <class F, class... Args> 
void post_forwarder(F f, Args&&... aArgs) { 
    f(std::forward<Args>(aArgs)..., 5); 
} 

LIVE DEMO

+1

それはうまくいきますが、問題は、提案された最小限の例がなぜ機能していないのか理解しようとしていますか? (それは、より複雑なシステムから抽出されているため、提案された代替機能が期待される機能を置き換えることはできません)。 –

+0

@AdN申し訳ありませんが、私はいくつかの重要なものがあり、返信できませんでした。それは非公式なコンテキストなので、失敗するのです。しかし、あなたはすでにあなたの答えを持っています。 – 101010

関連する問題