2016-09-12 11 views
3

を詰めていない次のプログラムを検討してください:私はそれが実行時に、次の(あるいはそう)の罰金と出力のコンパイルに期待`パラメータにcall`に該当する機能は、再帰的な拡張

#include <iostream> 


template <int I, typename T, typename ...Args> 
struct foo { 
    static void bar(const T& t0, const T& t1, const Args&... args) 
    { 
     std::cout << "(" << t0 << ", " << t1 << ") "; 
     foo::bar(args...); 
    } 
}; 

template <int I, typename T> 
struct foo<I, T> { 
    static void bar(const T& t0, const T& t1) 
    { 
     std::cout << "("<< t0 << ", " << t1 << ") " << std::endl; 
    } 
}; 


int main() { 
    foo<1, int, float>::bar(0, 1, 18.f, -7.f); 
    return 0; 
} 

を:

(0, 1) (18, -7) 

しかし、このコードはg++ -std=c++14 -pedantic -Wall -Wextra parampack.cpp(GCC 5.3.0)を介して生成される出力は次のとおり:

parampack.cpp: In function ‘int main()’: 
parampack.cpp:23:45: error: no matching function for call to ‘foo<1, int, float>::bar(int, int, float, float)’ 
    foo<1, int, float>::bar(0, 1, 18.f, -7.f); 
              ^
parampack.cpp:6:17: note: candidate: static void foo<I, T, Args>::bar(const T&, const T&, const Args& ...) [with int I = 1; T = int; Args = {float}] 
    static void bar(const T& t0, const T& t1, const Args&... args) 
       ^
parampack.cpp:6:17: note: candidate expects 3 arguments, 4 provided 
parampack.cpp: In instantiation of ‘static void foo<I, T, Args>::bar(const T&, const T&, const Args& ...) [with int I = 1; T = int; Args = {float}]’: 
parampack.cpp:23:25: required from here 
parampack.cpp:9:17: error: no matching function for call to ‘foo<1, int, float>::bar(const float&)’ 
     foo::bar(args...); 
       ^
parampack.cpp:6:17: note: candidate: static void foo<I, T, Args>::bar(const T&, const T&, const Args& ...) [with int I = 1; T = int; Args = {float}] 
    static void bar(const T& t0, const T& t1, const Args&... args) 
       ^
parampack.cpp:6:17: note: candidate expects 3 arguments, 1 provided 

私のようなバリエーションおよび順列のすべての種類試した:私はまさにを何が起こるか本当にわからないんだけど

template <int I, typename T, typename U, typename ...Args> 
struct foo { 
    static void bar(const T& t0, const T& t1, const U& u0, const U& u1, const Args&... args) 
    { 
     std::cout << "(" << t0 << ", " << t1 << ") "; 
     foo::bar(u0, u1, args...); 
    } 
}; 

を...私はそれがコンパイルさせるように見えることはできませんし、

なぜコンパイラはどの関数をインスタンス化するのか把握していませんか?

答えて

4

まず、コンパイラが示唆するように、引数の数が間違っています。 foo<1, int float>::bar()の署名は:

static void bar(int const&, int const&, float const&); 

3つの引数です。あなたは4番を通過しています。それで簡単なエラーです。

明らかにしようとしているのは、一度に2つの引数を選択することです。この場合、barの末尾の引数はfooの末尾の引数と同じではありませんので、あなたがしたい:再帰呼び出しをfoo::bar()に:第二の問題にもたらすでしょう

template <int I, typename T, typename ...Args> 
struct foo { 
    template <class... Extra> 
    static void bar(const T& t0, const T& t1, const Extra&... args) 
    { 
     std::cout << "(" << t0 << ", " << t1 << ") "; 
     foo::bar(args...); // <== (*) 
    } 
}; 

fooには、プライマリテンプレートの注入されたクラス名があります。それは実際にあなたのベースケースの専門化にあなたを得ることはありません。だから、そこには、あなたがしたい:

foo<I, Args...>::bar(args...); 
+0

「あなたは明らかにやろうとしているものは、一度に2つの引数を選択することです。この場合は、バーの末尾の引数がfooの末尾の引数と同じではありません。」 - >私が混乱していたこと!今私はそれをどのような型や数、引数にも適用できます。ありがとうございました! – dummydev

関連する問題