2012-07-19 80 views
3

我想通過一個模板參數列表,但沒有成功迭代模板參數列表?

的方式計算循環,我不能使用C++ 11可變參數模板功能,它需要在編譯時完成

我可以假設否定之後將不會有積極的論點

有什麼想法?

template< int F1, int F2 ,int F3> 
struct TemplatedClass 
{ 
    TemplatedClass(); 
    update() 
    { 
     /* 
      for each positive template argument 
      call a method 
     */ 
    } 
}; 
+0

固定的模板參數是多少? – 2012-07-19 13:46:39

+0

它是固定的,(雖然可以很長) – Pierre 2012-07-19 13:48:20

回答

3

由於您將有有限數量的模板參數,因此可以使用一系列if語句。

template<int F1, int F2 ,int F3> 
struct TemplatedClass 
{ 
    TemplatedClass(); 
    update() 
    { 
    if (F1 > 0) myfunc(); 
    if (F2 > 0) myfunc(); 
    if (F3 > 0) myfunc(); 
     // etc.* 
    } 
} 
+0

是啊,這個清單可能會很長,所以我想避免它,如果可能的話,但它可能是唯一的解決方案 – Pierre 2012-07-19 13:48:50

+0

@Pierre,我認爲你卡住了用它。 – ThomasMcLeod 2012-07-19 13:51:16

+1

@Pierre,你可以考慮將'int *'傳遞給靜態內存而不是大量的'int'。 – ThomasMcLeod 2012-07-19 13:53:28

2

有了固定的模板參數的個數,這樣一個簡單的代碼就可以了:

update() 
{ 
    if (F1 > 0) callAMethod(); 
    if (F2 > 0) callAMethod(); 
    if (F3 > 0) callAMethod(); 
} 

if語句表達式是編譯時間常數,所以優化器將其優化成代碼相當於要麼調用方法「未保護」(沒有分支),要麼根本不調用方法。換句話說,調用方法的決定將在編譯時由優化器進行,無需運行時成本。

1

或者使用輔助模板,如果你不知道優化器將擺脫if S的:

void functionToCall(int number) { /* ... */ } 

template<bool doCall> 
struct FuncCaller { 
    template<typename Callable> 
    FuncCaller(Callable func, int number) { func(number); } 
}; 

template<> 
struct FuncCaller<false> { 
    template<typename Callable> 
    FuncCaller(Callable, int) {} 
}; 

update() 
{ 
    FuncCaller<(F1 > 0)>(functionToCall, F1); 
    FuncCaller<(F2 > 0)>(functionToCall, F2); 
    FuncCaller<(F3 > 0)>(functionToCall, F3); 
} 
5

而是寫了一系列的if語句,你也可以把所有的參數到一個數組,迭代的通過它。這樣編譯器將無法優化你的代碼(你沒有指定是否需要),但它看起來會更清晰。例如。

template<int F1, int F2 ,int F3> 
struct TemplatedClass 
{ 
    TemplatedClass(); 
    update() 
    { 
     const int array[] = {F1, F2, F3}; 
     // replace this with std::for_each(...) with functors you need 
     for (int i = 0; i < sizeof(array)/sizeof(array[0]); ++i) 
     { 
      myfunc(array[i]); 
     } 
    } 
} 
+0

我喜歡這個解決方案,不幸的是myfunc在我的情況下也是一個模板,它不接受數組[i],因爲它不是恆定的。不管怎麼說,還是要謝謝你 – Pierre 2012-07-19 14:08:51

0

你可以嘗試這樣做,使用Boost元編程庫,但需要你改變類的模板定義,以騰出空間加速MPL參數。

你想加速做一個例子:: MPL是:

#include <boost/mpl/vector.hpp> 
#include <boost/mpl/empty.hpp> 
#include <boost/mpl/back.hpp> 
#include <boost/mpl/pop_back.hpp> 
#include <boost/mpl/if.hpp> 
#include <iostream> 

using namespace boost::mpl; 
template<class T> 
class Test { 
public: 
    void funcToCall() { 
    std::cout << "I'm called\n"; 
    } 
    void update(); 
}; 

template<class Y, class T> 
struct Update { 
    static void update(T* t) { 
    typedef typename pop_back<Y>::type vec_less; 
    if (back<Y>::type::value > 0) 
     t->funcToCall(); 
    Update<typename if_<empty<vec_less>, void, vec_less >::type, T>::update(t); 
    } 
}; 
template<class T> 
struct Update<void ,T> { 
    static void update(T* t) {} 
}; 

template<class T> 
void Test<T>::update() { 

Update<T, Test<T> >::update(this); 

} 


int main() { 
    Test<vector<int_<0>,int_<4>, int_<9> > > t; 
    t.update(); 
    return 0; 
} 

類「測試」將是你原來的「TemplatedClass」。現在不用獲取int模板參數的列表,只需要一個參數即boost :: mpl :: vector。這包含所有想要傳遞的整數,然後調用更新函數,該函數將遞歸調用結構「更新」中的更新方法,如果int大於0,將有責任調用「funcToCall()」方法。

我上面粘貼的程序的輸出是:

的MacBook-Pro的二馬塞羅:〜Kariddi $ ./test

我叫

我叫

當然,您需要本示例的Boost庫才能工作。

您可以找到有關MPL這裏:

http://www.boost.org/libs/mpl/doc/index.html

乾杯, 馬塞羅