2017-03-12 36 views
0

我希望做一個管道,在那裏我會指定一些加工類 作爲模板參數和模板將他們等之間傳遞數據傳遞的類的列表模板

所以我還挺與VC/IntelC合作,但不是鏗鏘聲/ gcc。 如何修復此代碼並使其具有可移植性?

在這裏你可以看到,微軟編譯器的理解:https://godbolt.org/g/0UBnTU

但用gcc /鐺我得到「明確的專業化非命名空間內」, 或「函數模板部分特例是不允許的」,如果我嘗試一種不同的方法。

#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,它的工作原理,爲什麼它不兼容?但我也有可觀的可變解決方案。 – Shelwien

+0

沒有函數模板專門化,所以你的'template <> static void x '重載是無效的,這就是你的編譯器應該抱怨的原因。使用'std :: integral_constant'重載或者想要達到你想要的。或者如果您有C++ 11支持,請使用可變參數模板。 –

回答

1

的原因,你的代碼是無效的,是因爲有在C++沒有函數模板專業化,因此template <> static void x<N>(Self* This){}是無效的。

什麼你可以不要超載:

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>()); 
} 

在你的情況下,它看起來像這樣:

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>) {} 
}; 

,因爲你可以」我滾我自己integer_constant這個例子沒有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,你不應該把第41行的<0> –