C++ 如何编写接受无限参数的函数?
我只能找到一种方法,函数可以接受不同数量的参数。C++ 如何编写接受无限参数的函数?,c++,function,variables,parameters,arguments,C++,Function,Variables,Parameters,Arguments,我只能找到一种方法,函数可以接受不同数量的参数。 是这样的: #include <iostream> #include <stdarg.h> using namespace std; void Print(int argumentAmount, ... ); int main() { Print(5,11,22,33,44,55); } void Print(int argumentAmount, ... ){ va_list arguments
是这样的:
#include <iostream>
#include <stdarg.h>
using namespace std;
void Print(int argumentAmount, ... );
int main()
{
Print(5,11,22,33,44,55);
}
void Print(int argumentAmount, ... ){
va_list arguments;
va_start(arguments, argumentAmount);
int parameter;
for(int i = 0; i < argumentAmount; ++i ){
parameter = va_arg(arguments, int);
cout << parameter << endl;
}
va_end(arguments);
return;
}
那么这个呢:
void Capitalize(/*all passed by reference*/);
int main(){
string s1 = "hello";
string s2 = "world";
string s3 = "this";
string s4 = "is";
string s5 = "a";
string s6 = "test";
string s7 = "as";
string s8 = "many";
string s9 = "strings";
string s10 = "as";
string s11 = "you";
string s12 = "want";
Capitalize(s1,s2);
Capitalize(s3,s4,s5,s6);
Capitalize(s7,s8,s9,s10,s11,s12);
return 0;
}
void Capitalize(/*all passed by reference*/){
//capitalize each string passed in
}
我所能想到的就是:-多次重载函数
-让函数接受某种类型的容器
如果这是不可能的,有人能解释一下为什么编译器不能完成这样的任务吗 快速简单的回答 <>对于C++,需要指定参数的数目或指示值结束的前哨值。 您的第一个示例是指定计数的一个很好的示例,您还可以执行以下操作:
void Print(const char *arg, ... ){
va_list arguments;
for (va_start(arguments, arg); arg != NULL; arg = va_arg(arguments, const char *)) {
cout << arg << endl;
}
va_end(arguments);
}
如果您想将其提升到下一个级别,可以混合一些C预处理器并执行以下操作:
#define mPrint(...) Print(__VA_ARGS__, NULL)
现在你可以说:
mPrint("fooo","bar");
宏将
NULL
终止调用。使用C++11中的可变模板,可以执行以下操作(请参阅)
#包括
#包括
无效输出(){
std::cout您可以有一个特殊的“尾随”参数(或者是nullptr
或者是指向某个硬编码的“魔术”字符串的指针),而不是传入计数,并且变量参数函数在看到尾随参数后应该停止提取更多参数。这可以稍微简化您的编码
您还可以将指针(引用)传递到包含(或指向/引用)字符串的容器。任何可以以某种方式链接所有单个参数的东西都可以(例如向量)
示例(可能不太习惯,但应作为一个示例):
我认为还有另一种可能的解决办法:
你可以让一个操作符超负荷“呃,你在顶部提供的解决方案是对底部提出的两个问题的回答。它是什么意思“修改它以便它输出字符串”?那么,你为什么不在数组或某种集合中传递字符串呢?我已经有一段时间没有看过C了-但是一个快速的google发现了这一点:这说明语法很好。编译器的唯一工作是编译C++代码。你问为什么C++语言不支持这种语法吗?顺便说一下,“无限的参数”有点陡峭;我今天才发现C编译器不需要支持127个以上的参数!哇,我想你刚刚帮助我理解了可变模板。等等,main中的第二个调用不会在内存中创建5个不同的函数,或者它实际上是递归的吗?是的,每个对输出的调用都有一组不同的模板参数s、 因此会导致不同的模板实例化。编译器是否会“在内存中”实际创建所有这些实例化或者内联到调用方取决于函数代码、优化级别等。为了将来的参考,您应该推迟发布,直到您测试并验证了您的声明。抱歉,我的错。事实上,我测试了它,它工作了一个例外:您不能在一个调用中传递多个类,但在多个调用中:Obj它应该工作,但它是很难说你做错了什么,因为你的代码片段语法不正确;你错过了返回类型。可能是你给了它void
。不要这样做
#define mPrint(...) Print(__VA_ARGS__, NULL)
mPrint("fooo","bar");
#include <string>
#include <iostream>
void Output() {
std::cout<<std::endl;
}
template<typename First, typename ... Strings>
void Output(First arg, const Strings&... rest) {
std::cout<<arg<<" ";
Output(rest...);
}
int main() {
Output("I","am","a","sentence");
Output("Let's","try",1,"or",2,"digits");
return 0;
}
#include <iostream>
#include <string>
#include <cstdarg>
#include <cctype>
#include <vector>
using namespace std;
void AntiCapitalize(vector<string*>& v);
void Capitalize(string* s, ...);
void Print(string* s, ...);
int main()
{
string s1 = "hello";
string s2 = "world";
string s3 = "this";
string s4 = "is";
string s5 = "a";
string s6 = "test";
string s7 = "as";
string s8 = "many";
string s9 = "strings";
string s10 = "as";
string s11 = "you";
string s12 = "want";
Capitalize(&s1, &s2, 0);
Capitalize(&s3, &s4, &s5, &s6, 0);
Capitalize(&s7, &s8, &s9, &s10, &s11, &s12, 0);
Print(&s1, &s2, 0);
Print(&s3, &s4, &s5, &s6, 0);
Print(&s7, &s8, &s9, &s10, &s11, &s12, 0);
vector<string*> v;
v.push_back(&s1);
v.push_back(&s2);
v.push_back(&s3);
v.push_back(&s4);
v.push_back(&s5);
v.push_back(&s6);
v.push_back(&s7);
v.push_back(&s8);
v.push_back(&s9);
v.push_back(&s10);
v.push_back(&s11);
v.push_back(&s12);
AntiCapitalize(v);
Print(&s1, &s2, 0);
Print(&s3, &s4, &s5, &s6, 0);
Print(&s7, &s8, &s9, &s10, &s11, &s12, 0);
return 0;
}
void Capitalize(string* s, ...)
{
va_list ap;
va_start(ap, s);
while (s)
{
string::size_type i = 0;
while ((*s)[i] != '\0')
{
(*s)[i] = toupper((*s)[i]);
i++;
}
s = va_arg(ap, string*);
}
va_end(ap);
}
void Print(string* s, ...)
{
va_list ap;
va_start(ap, s);
while (s)
{
cout << *s << endl;
s = va_arg(ap, string*);
}
va_end(ap);
}
void AntiCapitalize(vector<string*>& v)
{
vector<string*>::iterator it;
for (it = v.begin(); it != v.end(); it++)
{
string::size_type i = 0;
while ((**it)[i] != '\0')
{
(**it)[i] = tolower((**it)[i]);
i++;
}
}
}
HELLO
WORLD
THIS
IS
A
TEST
AS
MANY
STRINGS
AS
YOU
WANT
hello
world
this
is
a
test
as
many
strings
as
you
want
class OutputObject {
public:
// Some class functions/members
};
template<class T>
static operator << (OutputObject& out, T temp) {
cout << temp;
}
static OutputObject Obj = OutputObject();
#include "OutputObject.hpp"
#include <string>
using namespace std;
int main(void) {
string str = "Hello World";
Obj << 12 << str << 3.14f << "C++";
Obj << 12;
Obj << str;
return(0);
};