2016-11-18 80 views
1

我有一個類如下所示的可變參數模板成員函數(foo)。這個想法是跳過參數中的所有雙打,並用用戶提供的參數分配一個對象。變量模板函數重載

template <class T> 
    class Var { 
    public: 

     template <typename U, typename ...Args> 
     int foo(int index, Args... args) 
     { 
      T* p = new U(args...); 
      // save in an array at index 'index' 
     } 

     template <typename U, typename ...Args> 
     int foo (double index, Args... args) 
     { 
      // do something with index and skip it 
      return foo<U>(args...); 
     } 
    }; 

    class A { 
    public: 
     A (int i, const char *p) 
     { 

     } 
    }; 

    int main() 
    { 
     Var<A> var; 

     var.foo<A>(1.0, 2, 3, "Okay"); 
    } 

現在這個工程,有2個問題。

  • 強制多少個雙跳過。例如:跳過2個雙打,然後下一個參數應該是一個int。如果不是,則拋出錯誤。

  • 在此處,使用'int'來代替'double'。所以我們將跳過2個整數。下一個索引將是一個數組的'索引'。

基本上我想通過沒有。 ints跳過作爲類模板參數。

template <class T, int SKIP> 
class Var { 

並使用SKIP來確定跳過多少個整數。

是否有可能做這樣的事情?

+0

我認爲有可能做類似的事情,但是由此產生的代碼可能會相當醜陋和令人費解。這只是一個學術問題,還是有一個實際的問題,你正試圖解決?如果你提出一個確切的問題,例如你想要得到什麼確切的行爲,這可能會有所幫助。 –

+0

這更具學術性。我根據Novelocrat建議的方案在下面添加了一個解決方案。在我的代碼庫中有一個實際的用例,我們需要根據OR類型和子類型來存儲對象。所以查找函數是(int類型)或(int類型,int子類型)。但我並沒有在那裏使用這個計劃。爲了更簡單的解決方案,我使用了兩個專門的類,其中我使用不同的參數集來重新定義了相同的函數(函數名)。 – MGH

回答

1

所以這就是我從新奇主義者那裏得到的暗示。只是粘貼它聽到的記錄。

template <class T, int SKIP> 
class FooHelper { 
public: 

    template <typename U, typename ...Args> 
    static int foo_helper(int index, Args... args) 
    { 
     FooHelper<T, SKIP-1>::foo_helper<U>(args...); 
     return 0; 
    } 
}; 

template <class T> 
class FooHelper<T, 0> { 
public: 

    template <typename U, typename ...Args> 
    static int foo_helper (Args... args) 
    { 
     auto p = new U(args...); 
     return 0; 
    } 
}; 

template <class T, int SKIP> 
class Var { 
public: 

    template <typename U, typename ...Args> 
    int foo(Args ...args) 
    { 
     FooHelper<T, SKIP>::foo_helper<U>(args...); 
     return 0; 
    } 
}; 
1

爲了您SKIP目標,你可以做這樣的事情:

template <typename U, typename ...Args> 
int foo(Args ...args) { 
    return foo_helper<U, 0>(std::forward(args)); 
} 

template <typename U, int I, typename ...Args> 
int foo_helper(int index, Args ...args) { 
    return foo_helper<U, I+1>(std::forward(args)); 
} 

template <typename U, typename ...Args> 
int foo_helper<U, SKIP, Args...>(int index, Args ...args) { 
    blah = new U(std::forward(args)); 
    return foobar; 
} 

基本上,有一個算到目標,直到它達到剝離參數的方法。針對目標值進行專業化。

而且,不是說你可能會想forward的參數保存參考等

我相信C++ 14可能使一些這方面更容易,但我不是新的模板不夠熟悉元編程技術來解決這個問題。

+0

感謝您的回答。但是,我們不是在做功能模板的部分專業化嗎?它不編譯。但是與模板類專業化相同的技術也適用。 – MGH

+0

你說得對,它是功能模板的部分特化。我沒有想到通過上面的代碼或直接測試它。但是,是的,它總是可以包裝在類模板中以使其工作。 – Novelocrat