2016-02-25 49 views
0

我想繞過參數包,需要一點幫助。C++ 11比較參數包

看看下面這個人爲的例子,有沒有辦法將Args與T進行比較,並且只有在匹配時才允許bar()編譯?例如,如果我創建Task<void(int, char, float)>我想bar(float, char, float)不編譯,但bar(int, char, float)編譯得很好。這是否可行?

template <typename... Types> 
struct foo {}; 

template<typename T> 
struct Task; 

template<typename R, typename...Args> 
struct Task<R(Args...)> 
{ 
    template<typename... T> 
    std::enable_if<is_same<T, Args> 
    void bar(T... args) 
    { 
     //do something here 
    }   
}; 

int main() 
{ 
    Task<int(int)> task; 
    int a = 0; 
    float b = 1.0; 
    bool c = false; 

    //compiles 
    task.bar(a); 

    //none of these should compile 
    task.bar(b); 
    task.bar(c); 
    task.bar(a, b); 
    task.bar(a, b, c); 
} 
+0

也許使用元組'is_same'?我甚至不知道什麼是「T」和「參數」是什麼意思。 或者我只是誤解了語法。 – maxbc

+0

上面有很多問題。如果你沒有這個包,它就不會編譯。試着讓你的代碼與*參數完全一致。然後開始添加'...'s。 – Yakk

回答

0

首先,語法應爲:

template<typename R, typename...Args> 
struct Task<R(Args...)> 
{ 
    template<typename... T> 
    std::enable_if<is_same<tuple<T...>, tuple<Args...> >::value > bar(T... args) 
    { 
     //do something here 
    }   
}; 

哪個編譯罰款,因爲SFINAE的:當試圖實例bar(bool)例如,第一個實例失敗,布爾型,但一個實例存在執行時轉換參數的類型爲int。

爲了獲得預期的效果,你需要的硬型檢查實例化模板後發生:

#include <type_traits> 
#include <tuple> 

template<typename T> 
struct Task; 

template<typename R, typename... Args> 
struct Task<R(Args...)> 
{ 
    template<typename... OtherArgs> 
    void bar(OtherArgs... otherArgs) 
    { 
     static_assert(
      std::is_same<std::tuple<Args...>, std::tuple<OtherArgs...> >::value, 
      "Use same args types !" 
     ); 
     // Do something 
    } 
}; 

int main() 
{ 
    Task<int(int)> task; 
    // Compiles fine 
    task.bar(1); 
    // Fails to compile 
    task.bar('u'); 
    task.bar(0ul); 
    return 0; 
} 
+0

編輯:這是對建議直接使用'void bar(Args ... args)'的已刪除評論的迴應。 由於隱式轉換('float','bool','char'都可以隱式轉換爲'int'),所以這可以很好地編譯,這不會像OP預期的那樣工作。你可能會得到一個警告,但通常沒有錯誤(特別是像VC++那樣)。 – maxbc