dan*_*jar 3 c++ parameters templates function c++11
有三种类型的序列,也就是说std::string,int,int.在C++中是否有一个模板允许函数将无限数量的序列作为参数?
Function("Peter", 27, 89,
"Max", 25, 72,
"Frank", 32, 94,
"David", 31, 98);
Run Code Online (Sandbox Code Playgroud)
问题是" 你对这个序列有什么看法 ".
可以采用任意一系列参数并将它们3乘3给一个只需3的函数:
void Function(string n, int a, int b)
{ /* base action here */ }
template<class... Others>
void Function(string n1, int a1, int b1, const Others&... t)
{
Function(n1, a1, b1);
Function(t...);
}
Run Code Online (Sandbox Code Playgroud)
它仅在参数类型重复匹配基函数时才编译.
以下是我想到的几种方法:
可变参数模板: C++ 11
(由Emilio Garavaglia的回答涵盖,所以我不再重复)
initializer_lists: C++ 11
(类似于ChriZzZ的答案,但改为std::initializer_list直接使用)
struct Sequence {
std::string name;
int numberA;
int numberB;
};
#include <initializer_list>
void Function(std::initializer_list<Sequence> aLotOfData)
{
for(const Sequence& s : aLotOfData)
{
// do operations on s.name, s.numberA, s.numberB
}
}
//usage example
Function({ {"Peter", 27, 89}, {"Max", 25, 72} });
Run Code Online (Sandbox Code Playgroud)
(这里结束了直截了当的解决方案列表)
重叠N的参数的函数:
void Function(string n1, int a1, int b1) { /* ??? */ }
void Function(string n1, int a1, int b1, string n2, int a2, int b2) { /* ??? */ }
void Function(string n1, int a1, int b1, string n2, int a2, int b2, string n3, int a3, int b3) { /* ??? */ }
//usage example
Function("Peter", 27, 89, "Max", 25, 72);
Run Code Online (Sandbox Code Playgroud)
实际上它并没有那么糟糕 - 如果你可以假设没有人会用超过N args(琐事:C标准建议C编译器支持128个参数的最小限制)调用它并且你不会手动编码(使用预处理器,但不一定是C预处理器 - 因为它是预处理的最低公分母.Boost在非C++ 11代码中使用自己的预处理器作为变量参数.或者你可以用C++程序生成C++代码并在源代码中包含输出文件代码 - 现在是C++元编程;-)).
数组初始化并传递给函数(或者使用指针和sizeof):
struct Sequence
{
std::string name;
int numberA;
int numberB;
};
#include <cstddef>
template<std::size_t N>
void Function(Sequence (&data)[N])
{
for(std::size_t i = 0; i < N; ++i)
{
// do operations on data[i].name, data[i].numberA, data[i].numberB
}
}
//usage example
Sequence args[] = { {"Peter", 27, 89}, {"Max", 25, 72} };
Function(args);
Run Code Online (Sandbox Code Playgroud)
类似的解决方案可以在C中使用(在C99中,您甚至可以使用复合文字来提供内联参数)
方法/功能/操作员链接:
struct Function
{
const Function& operator()(string name, int na, int nb) const
{
// do operations to name, na, nb
return *this;
}
void operator() const
{
//base case
//optional here - return values
}
};
//usage example
Function()("Peter", 27, 89)("Max", 25, 72)();
Run Code Online (Sandbox Code Playgroud)
链接用于C++ iostreams和Boost.Assign.在这个实现中,调用者可能忘记包含最后的parens,而函数将不会做最后的事情 - 肯定会有更好的实现.
C varargs:
#include <cstdarg>
void Function(std::size_t count, ...)
{
va_list ap;
va_start(ap, count);
for(std::size_t i = 0; i < count; ++i)
{
string name = va_arg(ap, const char*);
int na = va_arg(ap, int);
int nb = va_arg(ap, int);
// do operations on name, na, nb
}
va_end(ap);
}
//usage example (the first argument refers to count of arguments - it has to match)
Function(2, "Peter", 27, 89, "Max", 25, 72);
Run Code Online (Sandbox Code Playgroud)
非常非常糟糕的解决方案.我们不得不丢弃std::string作为参数并将其替换const char*为非POD,不能传递给varargs函数(或者我们可以传递指针std::string).请注意,此处的任何错误都将导致未定义的行为.编译器不会检查args的类型,并且会盲目地相信我们传递了正确类型的参数.