2017-03-12 5 views
0

へのクラスのリスト、テンプレート引数として を渡すと、テンプレートはそれらの間でデータを渡すなど私はいくつかの処理クラスを指定したい私は、パイプラインを作りたいテンプレート

だから私は、ちょっとしましたそれはVC/IntelCで動作するようになりましたが、clang/gccでは動作しませんでした。 このコードを修正してポータブルにするにはどうすればよいですか?

ここでは、Microsoftのコンパイラはそれを理解していることを見ることができます:https://godbolt.org/g/0UBnTU

しかし、GCC /打ち鳴らすと、私は、「非名前空間スコープ内の明示的な特殊化を」取得 場合、または「関数テンプレート部分的な特殊が許可されていません」よ私は別のアプローチを試みます。したがって、template <> static void x<N>(Self* This){}が無効である、C++には、関数テンプレートの特殊化がないため

#include <stdio.h> 

struct proc1 { int x[1]; }; 
struct proc2 { int x[2]; }; 
struct proc3 { int x[3]; }; 
struct proc4 { int x[4]; }; 

template< int N > struct S1; 
template<> struct S1<0> { typedef proc1 t; }; 
template<> struct S1<1> { typedef proc2 t; }; 
template<> struct S1<2> { typedef proc3 t; }; 
template<> struct S1<3> { typedef proc4 t; }; 

template< int _N, template<int i> class Sx > 
struct S2 { 
    enum{ N=_N }; 

    void* tbl[N]; 

    template< typename TT > struct print { 
    template< typename Self > 
    static void x(Self* This, int ii) { 
     This->tbl[ii] = new TT; 
     printf("sizeof(Sx<%i>)=%i sizeof(Self)=%i\n", ii, int(sizeof(TT)), int(sizeof(Self))); 
    } 
    }; 

    template< class Self, template<typename TT> class func > 
    struct for_all { 
    template< int ii > static void x(Self* This) { 
     func< typename Sx<ii>::t >::x(This,ii); 
     x<ii+1>(This); 
    } 
    template<> static void x<N>(Self* This) {} 
    }; 

    void test(void) { 
    printf("N=%i\n", N); 
    for_all<S2,print>::x<0>(this); 
    } 

}; 

S2<4,S1> X; 

int main() { 
    X.test(); 
} 
+0

variadicのパラメータパックは何ですか? –

+0

しかしこれはC++ 98で動作しますが、互換性を損なうのはなぜですか?しかし、私はvariadicソリューションもかなりのはずだ。 – Shelwien

+0

関数テンプレートの特殊化がないので、 'template <> static void x 'オーバーロードは無効です。これはあなたのコンパイラが文句を言うべき理由です。 'std :: integral_constant'などでオーバーロードを使用するか、好きなものを実現するのが好きです。または、C++ 11のサポートがある場合は、バリデーショナルテンプレートを使用してください。 –

答えて

1

あなたのコードは無効である理由があります。

は何がのオーバーロードされないことができ:お使いの場合には

template <int I> 
struct integer_constant {}; 

template <int I> 
void foo(integer_constant<I>) 
{ 
    std::cout << I << '\n'; 
    foo(integer_constant<I - 1>()); 
} 

void foo(integer_constant<0>) 
{ 
    std::cout << 0 << '\n'; 
} 

int main() 
{ 
    foo(integer_constant<5>()); 
} 

、それは次のようになります。「することができますので、私は、この例ではinteger_constant自分を巻いてきた

template< class Self, template<typename TT> class func > 
struct for_all { 
    template< int ii > static void x(Self* This, integer_constant<ii>) { 
     func< typename Sx<ii>::t >::x(This,ii); 
     x(This, integer_constant<ii + 1>()); 
    } 
    static void x(Self* This, integer_constant<N>) {} 
}; 

tはC++ 11を持っていますが、可能ならば何かの標準を使うべきですstd::integral_constant

+0

面白いアイデアのようですが、私はそれをチェックします。 – Shelwien

+0

同じケース:VC/IntelCで動作しますが、gcc/clangでは動作しません - https://godbolt.org/g/a6AO1q – Shelwien

+0

@Shelwien、https://godbolt.org/g/YDJplL、 <0>は41行目 –

関連する問題