允许我说,我知道这个问题不适合大多数约定(如果有的话),但是出于对编程语言(C ++)的好奇和热爱,我还是会问这个问题。 随时用下面的答案或评论纠正我。
问题:
“我们可以在C ++中制作 variadic函数来接受多个参数(可能以前未知)的数据类型吗?实施?”
示例:
JavaScript示例
function buildArgs(... args) {
let iterator = 0,
length = args.length;
for (iterator; iterator != length; iterator += 1) {
let arg = args[iterator];
build(arg)
}
}
buildArgs(1); // Valid
buildArgs(1, "Hello"); // Valid
buildArgs(1, "Hello", null) // Valid
(假设的)C ++示例:
template <class... Args, typename data>
inline void buildArgs(Args... args) {
int iterator = 0,
length = sizeof args;
for (iterator; iterator != length; iterator += 1) {
data arg = args[iterator];
build(arg);
}
}
buildArgs(1); // Valid
buildArgs(1, "Hello"); // Valid
buildArgs(1, "Hello", NULL); // Valid
从给出的示例中,被认为对函数buildArgs
有效的参数可以是任何数据类型(char
,int
,std::string
等),而函数buildArgs
可以接受任意数量的有效参数。
我已经对C ++中的可变参数函数和模板进行了一些较小的研究,但我还没有找到答案。
再次,我不能说这个功能的实用性,但是我非常想知道是否有可能。
链接:
• C中不同类型参数的变参函数:variadic functions with different types of arguments in c
•接受所有类型作为函数中的参数:Accept all types as argument in function
• C编程:https://en.wikibooks.org/wiki/C_Programming/stdarg.h
• C ++参考-参数包:https://en.cppreference.com/w/cpp/language/parameter_pack
• C ++参考-折叠表达式:https://en.cppreference.com/w/cpp/language/fold
• C中可变参数的数量:Variable number of arguments in C++?
结论:
感谢您抽出宝贵的时间阅读我的问题,并感谢您的回答。
答案 0 :(得分:2)
参数包是当前的C ++方式:
template<typename... Args> auto f(Args &&...args);
有了背包,你不能做很多,但仍然可以做些什么:
I。将它们存储在元组或(如果可能)数组或initialization_list
s中:
auto t = std::tuple(std::forward<Args>(args)...);
CommonType a[] = {args...};
std::set<int> mySet{args...};
II。将它们用作函数参数(请参见上面的元组构造。)C ++中一个可识别包装的运算符是sizeof...
:
std::size_t currentArity = sizeof...(Args);
III。折叠包:
bool any = (args || ...);
(std::cout << ... << args);
set::set<int> myOtherSet;
(myOtherSet.insert(args), ...);
依此类推。
答案 1 :(得分:0)
对于C ++ 11,情况要复杂得多: Live example。
template <typename T>
void printArgs(T &&x)
{
std::cout << std::forward<T>(x) << " - ";
}
template <typename FirstT, typename ...Args>
void printArgs(FirstT &&first, Args&&...remaining)
{
printArgs(std::forward<FirstT>(first));
printArgs(std::forward<Args>(remaining)...);
}
如您所见,您没有参数迭代器。而是使用伪递归。
此外,还应考虑一种叫做“完美转发”的奇怪事物。
在这里您可以看到live example which gives debug information
问题是:
“我们可以用C ++制作可变参数函数来接受以下参数吗? 多种(可能以前未知)的数据类型以及如何处理 被实施?
答案为是。 C ++中的模板在使用时会实例化。因此,默认情况下,它们可以使用任何类型,直到遇到内部问题为止,例如某些功能不适用于特定类型。
在上面的示例中,您可以定义自定义类型,并且printArgs
将失败,因为新类型没有operator<<(std::ostream &, const NewType &)
。要解决该问题,您只需提供这样的运算符,printArgs
就可以开始使用新类型了。
还有其他方法,例如CRTP (Curiously recurring template pattern)等。 C ++中的模板主题相当长且复杂。
答案 2 :(得分:0)
我们可以在C ++中制作可变参数函数来接受多种(可能以前未知)数据类型的参数吗?
是的。标头<cstdarg>
中有库工具,可以简化此操作。
它们是:
-va_start
(启用对可变参数函数参数的访问),
-va_arg
(访问下一个可变参数函数参数),
-va_copy
(在C ++ 11中引入,它制作了可变参数函数参数的副本,
-va_end
(结束对可变参数函数的遍历)和
-va_list
(包含va_start
,va_arg
,va_end
和va_copy
所需的信息)。
另外,C,Go,C#,PHP,Java,JavaScript,Python,Perl 6支持此功能。