2013-12-09 100 views
2

我有一個類模板這需要一個類型和一個指針,它指向類型的變量:與數據指針可變參數模板模板

template <typename arg_t, arg_t* storage> 
class Value; 

我有一個第二類模板,採用可變數目的模板

template <typename... arg_t> 
class ValueList; 

我想要讓這個只有類型的類模板的價值可以作爲由局部專業化參數值列表:第一類。這是我所期待的工作:

template <typename... arg_t, arg_t*... storage> 
class ValueList<Value<arg_t, storage>...>; 

在Visual C++ 2013年,我得到的錯誤:'arg_t*': parameter pack cannot be expanded in this context。請注意,這種類型的擴展適用於只有類型的模板,IE ...

template <typename...> 
class A; 

template <template <typename, typename> class B, typename... C, typename... D> 
class A<B<C, D>...> {}; 

...有效。什麼使這種情況有所不同,以及達到預期效果的正確語法是什麼?

用法:

int a; 
float b; 

int main(int argc, char** argv) { 
    ValueList<Value<int, &a>, Value<float, &b> > list; 
} 
+0

你能告訴我們這種類型的用法嗎?但是,它爲我工作在gcc/clang。 – ForEveR

+0

@ForEveR增加了OP的使用。 – NmdMystery

+0

@ForEveR我只是在MinGW中試過它,它也在那裏工作。 Visual C++真的在後面嗎? – NmdMystery

回答

1

根據§14.1/ 15字符串中的代碼是不允許

template <typename... arg_t, arg_t*... storage> 

A template parameter pack that is a pack expansion shall not expand a parameter pack declared in the same template-parameter-list. [ Example:

// ... 

template<class... T, T... Values> struct static_array;// error: Values expands template type parameter 
                 // pack T within the same template parameter list 

—end example ]

1

一位評論建議嵌套模板檢查,所以這裏是一個實現。爲了好玩,我使用了一個名爲MyTag的空結構,其中只有class Value<>應該從作爲合法參數的標記繼承。我想不出一個更簡潔的方法來做到這一點。

using namespace std; 

struct MyTag {}; 

template <typename arg_t, arg_t* storage> 
class Value : MyTag {}; 

//Iterate throught the list, checking each parameter 
template<typename F, typename... T> 
struct CheckValuePack{ 
    static const bool value = is_base_of<MyTag,F>::value && 
          CheckValuePack<T...>::value; 
    typedef enable_if<is_base_of<MyTag,F>::value && 
        CheckValuePack<T...>::value 
        > Checked; 
}; 

//Check the last parameter 
template<typename F> 
struct CheckValuePack<F>{ 
    static const bool value = is_base_of<MyTag,F>::value; 
}; 

template <typename... T> 
class ValueList { 
    CheckValuePack<T...> checked; //perform the check 
}; 

int a; 
float b; 

int main(int argc, char** argv) { 
     ValueList<Value<int, &a>, Value<float, &b> > list; 
     //ValueList<Value<int, &a>, Value<float, &b>, int > list; //compile time error 
     return 0; 
} 

注意CheckValuePack<T...>ValueList<>也可以繼承。