变量参数
回答
对于最多5个参数都是相同的类型,简单的重载可以做到这一点。
更为通用,支持任意数量的相同类型的参数,只需传递一个集合,如std::vector
。
对于在每次调用中动态构建这种集合的C++ 03技术,请参阅my other answer;对于C++ 11,如果您不需要支持Visual C++,则可以使用大括号初始值设定项列表作为实际参数。
我知道参数类型,他们通常小于5
如果不会大于5
,然后简单的过载可以做的工作。调用接受来自所有其他接受少于5个参数的重载参数的maximam数量的重载,或者定义一个worker(内部)函数,从重载中调用它。
如果可能的话,您可以使用某些参数的默认值,如果这有助于减少重载函数的数量。
在C++ 11中,您可以使用variadic-template。
我不明白为什么要使用可变参数模板,如果参数类型是已知的,并且显然是固定的? – 2012-08-09 06:40:34
@JakobS。如果真正的最大数量的参数是未知的(OP表示*通常*小于5),并且C++ 11可变参数模板是一种可能性,那么我会说C++ 11可变参数模板显然是手动的,最好的解决方案。 – 2012-08-09 07:04:46
考虑重载支持3个参数。有5种可能的参数类型,你需要5^3 = 125个重载,加上25个重载的两个参数,5个重载的1个参数和单个无参数的版本;一般来说,对于**(5 ^(n + 1)-1)/ 4重载**的n个参数。这对我的口味有点太过分了。 – 2012-08-09 07:07:56
您应该能够使用va_list实现传递可变参数。
作为一般的C++ 03解决方案,您可以提供一个setter,它返回对其所调用的对象的引用,以便可以再次调用它。然后再次。以此类推,称为链接。
这与iostreams使用的方案相同,用于operator<<
。
E.g.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
void foo(char const s[])
{
cout << s << endl;
}
class StringBuilder
{
private:
string s_;
template< class Type >
string fastStringFrom(Type const& v)
{
stringstream stream;
stream << v;
return stream.str();
}
char const* fastStringFrom(char const* s)
{
return s;
}
string const& fastStringFrom(string const& s)
{
return s;
}
public:
template< class Type >
StringBuilder& operator<<(Type const& v)
{
s_ += fastStringFrom(v);
return *this; // Supports chaining.
}
operator string const&() const { return s_; }
operator char const*() const { return s_.c_str(); }
};
int main()
{
typedef StringBuilder S;
foo(S() << "6*7 = " << 6*7 << "."); // Any number of arguments.
}
相反转换参数值,以文字,你就去做什么,那就是你需要的。例如,对于一组固定的可能类型,您可以将参数存储在集合中。
如果您不需要支持Visual C++编译器,那么也可以使用C++ 11 可变参数模板。
您可以:
- 如果你使用C++ 11可以使用可变参数模板,否则......
- 提供重载
- 其默认一些哨兵值,您可以识别ALA
f(const T& v1 = missing, const T& v2 = missing, ...) { if (v5 != missing) ...
- 创建可任选地从数据类型构造并具有布尔一个简单的辅助模板使用参数来跟踪它是否是
- 您可能需要支持没有默认构造函数的类型,方法是使用新建/删除(简单且安全但缓慢)或者将对齐的缓冲区放置到
new
中,手动销毁等(错误且更容易出错但更快)
个
- 您可能需要支持没有默认构造函数的类型,方法是使用新建/删除(简单且安全但缓慢)或者将对齐的缓冲区放置到
- 一些编译器具有可变参数宏支持
- 如果你准备改变调用语法一点,你可以使用任意数量的事情:
- 接受载体(使用工会或变体,如果类型不同)
- 接受的阵列(可能使用
template <size_t N> void f(T (&data)[N]) { ... }
特技有编译器可以自动提供数组的大小) - 某种LHS的反对其可使用操作者提供额外的值,如
operator,
或operator<<
- 1. PHP变量参数
- 2. C变量参数
- 3. 可变数量的参数
- 4. 函数参数变量名
- 5. 基于变量的参数数量
- 6. 变量更新时变量参数发生变化的函数
- 7. java变量和参数
- 8. 参数类类型变量
- 9. 局部变量vs参数
- 10. C中的参数变量
- 11. Regexp自变量参数
- 12. 变量上的空参数
- 13. 静态变量GET参数
- 14. 双变量参数列表
- 15. 参数来自变量?
- 16. PHP变量的URL参数
- 17. 加载参数变量Unity
- 18. Laravel:鉴于变量+参数
- 19. 变量类型参数
- 20. 变量jquery参数名称
- 21. 参考变量数组
- 22. 变量的Python参数
- 23. 使用可变参数类型参数的变量函数
- 24. 参数作为变量数量的参数
- 25. 变量函数中的变量数据类型参数
- 26. C++ - 常量参数和类变量pessimization?
- 27. jquery函数参数,对象和变量
- 28. VB中参数的可变数量
- 29. 变量参数和函数重载
- 30. 作为函数参数变量?
用google搜索“variadic arguments C++”。 – 2012-08-09 06:22:02
-1问题措词与预期问题有关。 – 2012-08-09 07:25:08
这是为什么标记C?两者的答案会非常不同。在C中,你可以用宏来实现,但是你的反升压声明似乎表明你不会喜欢它。 – 2012-08-09 07:59:43