2015-11-03 228 views
1

我在周圍工作的問題在下面的代碼中的問題... C++可變參數類模板和成員函數

#include <functional> 

template<typename... ARGS> 
class MyClass { 
public : 
    void function(ARGS... args) 
    { 
    } 
}; 

int main(int argc, char * argv[]) 
{ 
    MyClass<int>  myClassInt;  // works fine 
    MyClass<int, float> myClassIntFloat; // works fine 
    MyClass<void>  myClassVoid;  // <---- won't compile 

    return 0; 
} 

鏘相當正確地拒絕編譯這個,如果我實例化無效 MyClass的,抱怨MyClass <void> :: function不是一個合法的定義。然而,我所需要的真正的類需要能夠在void上實例化這種類型的東西。我一直在盯着這個很長一段時間,我堅持什麼模板SFINAE jiggery-pokery我需要解決它。

+0

我意識到我需要以某種方式專注於** void **的情況,但是我無法看到一種不會被一般可變參數情況所捕獲的方法。 – brunobignose

+1

因爲使用'void'相當於聲明瞭無效的成員函數'void MyClass :: function(void args)'。專業化的確是解決你的問題的關鍵。 –

+0

爲什麼不能'MyClass <>'? – Yakk

回答

4

要麼使用MyClass<>在使用點,或本hack:

template<typename... ARGS> 
class MyClass { 
public : 
    void function(ARGS... args) 
    {} 
}; 
template<> 
class MyClass<void>:public MyClass<> { 
public : 
    using MyClass<>::MyClass; // inherit ctors 
}; 

也有可能是你需要在MyClass<void>做作爲一個相對透明代理MyClass<>其他的事情。

我們可以通過不直接使用MyClass來避免這些問題。

template<typename... ARGS> 
class MyClass_t { 
public : 
    void function(ARGS... args) 
    {} 
}; 

template<class...Args> 
struct MyClass_helper { 
    using type=MyClass_t<Args...>; 
}; 
template<> 
struct MyClass_helper<void>:MyClass_helper<> {}; 
template<class...Args> 
using MyClass=typename MyClass_helper<Args...>::type; 

現在,MyClass<void>擴展到MyClass_t<>,並MyClass<int, float>擴展到MyClass_t<int,float>

我們不直接使用MyClass_t,而是通過MyClass<...>來命名。這種技術的缺點是MyClass<???>如果用作函數參數是一個非推導的上下文;因此您必須在這些情況下使用MyClass_t<???>,並且他們不會看到void

我的首選解決方案是直接使用MyClass<>而不是MyClass<void>

+0

感謝您的答案!我不知道如何將它實例化爲MyClass <>,這看起來完美無缺。 – brunobignose

相關問題