Nic*_*ton 29 c++ ellipsis variadic-functions
有人可以向我解释为什么C++,至少据我所知,没有实现一个强类型的省略号函数,这是有效的:
void foo(double ...) {
// Do Something
}
Run Code Online (Sandbox Code Playgroud)
这意味着,简单地说:'用户可以将可变数量的术语传递给foo函数,但是,所有术语必须是双倍的'
edm*_*dmz 23
有
void foo(std::initializer_list<double> values);
// foo( {1.5, 3.14, 2.7} );
Run Code Online (Sandbox Code Playgroud)
这非常接近.
您也可以使用可变参数模板,但它会更具有话语性.至于实际的原因,我会说引入新语法的努力可能不值得:你如何访问单个元素?你怎么知道什么时候停下来?比什么让它更好std::initializer_list呢?
C++确实有更接近的东西:非类型参数包.
template < non-type ... values>
Run Code Online (Sandbox Code Playgroud)
像
template <int ... Ints>
void foo()
{
for (int i : {Ints...} )
// do something with i
}
Run Code Online (Sandbox Code Playgroud)
但是非类型模板参数(uhm)的类型有一些限制:double例如,它不能.
Mat*_* M. 15
从历史上看,省略号语法...来自C.
这种复杂的野兽被用来驱动printf式的功能,并且与使用va_list,va_start等等...
如你所知,它不是类型安全的; 但是C远不是类型安全的,它与void*任何指针类型的隐式转换,它的隐式截断积分/浮点值等等...
因为C++作为C的超集尽可能接近,所以它继承了C的省略号.
自成立以来,C++实践得到了发展,并且一直在努力推动更强的打字.
在C++ 11中,这最终达到了:
foo({1, 2, 3, 4, 5})printf的例子变量模板实际上...在语法中重用省略号,表示类型或值的包,并作为解包运算符:
void print(std::ostream&) {}
template <typename T, typename... Args>
void print(std::ostream& out, T const& t, Args const&... args) {
print(out << t, args...); // recursive, unless there are no args left
// (in that case, it calls the first overload
// instead of recursing.)
}
Run Code Online (Sandbox Code Playgroud)
注意3种不同的用途...:
typename... 声明一个可变参数类型Args const&... 宣布一包参数args... 在表达式中解压缩包Que*_*tin 11
可变模板和SFINAE已经可以实现:
template <bool...> struct bool_pack;
template <bool... v>
using all_true = std::is_same<bool_pack<true, v...>, bool_pack<v..., true>>;
template <class... Doubles, class = std::enable_if_t<
all_true<std::is_convertible<Doubles, double>{}...>{}
>>
void foo(Doubles... args) {}
Run Code Online (Sandbox Code Playgroud)
感谢Columbo提供了很好的all_true技巧.您还可以在C++ 17中使用折叠表达式.
由于后来和即将出现的标准都集中在terser语法(简洁的for循环,隐式函数模板......)上,所提出的语法很可能在标准的一天内结束;)
| 归档时间: |
|
| 查看次数: |
7567 次 |
| 最近记录: |