2013-12-09 101 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<>也可以继承。