2016-03-21 57 views
4

我在写一个容器存储类模板,它封装了一个专用的std::array以便为其添加一些功能。模板parametrises值的数量,具体如下:取决于整数模板的可变数量的构造函数参数

template<size_t N> class Vector { 
private: 
    array<double, N> vals; 
public: 
    [...] 
}; 

我想只接受N双打,填补了数组构造函数的类,但我不能找到一个很好的办法做到这一点。可变参数不提供检查其中有多少个的机制,所以他们是正确的。参数包不会进行浮点升级,但如果我只能弄清楚如何使用它们,我会愿意处理这个问题。

我试过下面的方法,在Member function template with the number of parameters depending on an integral template parameter的答案中,但我不明白enable_if<>::type=0的意义部分。我试着简单地复制那些代码(尽管我很想知道它是如何工作的,我曾经在其他地方看到过人们使用::value,但是我找不到任何有关为什么的文档),但是扩展结果参数包并没有' t似乎工作。我对参数包的其他担忧是,我不确定他们会确保所有参数的类型相同。

我试过在构造函数的主体中初始化列表的大小上运行一个static_assert,但是当然在编译时列表的大小不是常量,所以也不起作用。

这里有标准的方法吗?我只是使用参数包错了?


更新: 我已经得到了我在上面的部分工作挂钩答案的办法:

template<size_t N> class Vector { 
private: 
    array<double, N> vals; 
public: 
    template <typename ...T, 
      typename enable_if<sizeof...(T) == N, int>::type = 0> 
    Vector(T ...args) { 
     vals = {args...}; 
    } 
}; 

现在的问题是,在模板中的enable_if期限意味着,当我一个初始化Vector用,例如,

Vector<3> V {1.0, 2.0, 3.0}; 

它要求一个模板特Vector<3>::Vector<double, double, double, 0>大鼠她比<double, double, double>。我如何摆脱模板中的这个杂散术语?

+0

为什么你的构造函数没有'array '参数?然后使用'Vector <3> {{1,2,3}}'。 – Simple

+1

为什么你想摆脱这个流浪的术语? – Holt

+1

更改'Vector(T ... args){vals = {args ...}; }'to'Vector(T ... args):val {args ...} {}' –

回答

2

通过以下Member function template with the number of parameters depending on an integral template parameterVariadic templates with exactly n parameters,得到它使用下面的代码。

template<size_t N> class Vector { 
private: 
    array<double, N> vals; 
public: 
    template <typename ...T, 
      typename enable_if<sizeof...(T) == N, int>::type = 0> 
    Vector(T ...args) : vals{args} {} 
}; 
+0

您可以通过添加另一个参数,例如'typename = decltype(std :: array {{std :: declval ()...}})来使它更加*更多* sfinaebla' –

5

不要让你这个意思:

可变参数不提供一个机制,以检查其中不乏 怎么有,所以他们是对的了

template <typename ...T> 
Vector(T... args) { 
    static_assert(sizeof...(args) <= N, "oops"); 
} 

应该工作..

+2

不错。我不知道['sizeof ...'](http://en.cppreference.com/w/cpp/language/sizeof ...) – wally

+1

这产生''args'并不是指一个参数包'。我不认为sizeof扩展适用于老式的可变参数和参数包。除了这个问题,static_asserts是否能够正确地阻止被选中的超载,或者如果assert失败,它们会被卡住吗? – TroyHurts

+1

@TroyHurts'static_asserts'不会阻止重载被选中,因为你应该使用'std :: enable_if'来解释你链接的帖子。 – Holt

2

你可以通过另外一些模板专业化的技巧产生大小合适的包:

template <size_t N, class = std::make_index_sequence<N>> 
class Vector; 

template <size_t N, size_t... Is> 
class Vector<N, std::index_sequence<Is...>> 
{ 
private: 
    std::array<double, N> vals; 

    template <size_t > 
    using double_ = double; 
public: 
    Vector(double_<Is>... vals) 
    { 
     ... 
    } 
}; 

这是一个非模板构造函数,它需要Ndouble s。

+0

伟大的答案 - 我会指出,1)这是唯一的答案(在这个线程中),允许支持初始化构造函数的参数(例如'Vector vec {{1,2},{2,3}};'),2)由于构造函数不是模板化的,所以它可以被继承,这对于使用可变参数模板来处理这种解决方案非常有用。 – Holt

相关问题