dav*_*vid 10 c++ templates variadic-functions
是否可以创建一个带有可变数量参数的模板函数,例如,在此类Vector< T, C >构造函数中:
template < typename T, uint C >
Vector< T, C >::Vector( T, ... )
{
va_list arg_list;
va_start( arg_list, C );
for( uint i = 0; i < C; i++ ) {
m_data[ i ] = va_arg( arg_list, T );
}
va_end( arg_list );
}
Run Code Online (Sandbox Code Playgroud)
这几乎可以工作,但如果有人调用Vector< double, 3 >( 1, 1, 1 ),只有第一个参数具有正确的值.我怀疑第一个参数是正确的,因为它double在函数调用期间被转换为a ,而其他参数被解释为ints然后将这些位填充到a中double.通话可以Vector< double, 3 >( 1.0, 1.0, 1.0 )产生预期的效果.有没有一种首选方式来做这样的事情?
唉,现在没有好办法做到这一点.大多数需要做类似事情的Boost包使用宏技巧来定义这样的事情:
template < typename T >
Vector< T >::Vector( T )
{ ... }
template < typename T, uint C >
Vector< T, C >::Vector( T t, C c1 )
{ ... }
template < typename T, uint C >
Vector< T, C >::Vector( T t, C c1, C c2 )
{ ... }
template < typename T, uint C >
Vector< T, C >::Vector( T t, C c1, C c2, C c3 )
{ ... }
Run Code Online (Sandbox Code Playgroud)
宏生成一些设置数(通常约为10个)版本,并提供一种机制来在扩展构造之前更改参数的最大数量.
基本上,这是一个真正的痛苦,这就是为什么C++ 0x引入了可变长度模板参数和委托方法,可以让你干净(安全)地完成这项工作.在此期间,您可以使用宏来执行此操作,也可以尝试使用支持(部分)这些新实验功能的C++编译器.GCC对此很好.
但要注意的是,由于C++ 0x实际上还没有出现,所以事情仍然会发生变化,而且您的代码可能与标准的最终版本不同步.此外,即使在标准出现之后,也会有5年左右的时间,在此期间许多编译器只会部分支持标准,因此您的代码将不会非常便携.
这段代码看起来很危险,我认为你对它不起作用的原因的分析是正确的,编译器在调用时无法知道:
Vector< double, 3 >( 1, 1, 1 )
Run Code Online (Sandbox Code Playgroud)
那些应该作为双打传递。
我会将构造函数更改为:
Vector< T, C >::Vector(const T(&data)[C])
Run Code Online (Sandbox Code Playgroud)
相反,让用户将参数作为数组传递。另一种丑陋的解决方案是这样的:
template < typename T, uint C >
Vector< T, C >::Vector(const Vector<T, C - 1>& elements, T extra) {
}
Run Code Online (Sandbox Code Playgroud)
并像这样调用它(使用一些 typedef):
Vector3(Vector2(Vector1(1), 1), 1);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15174 次 |
| 最近记录: |