C++에서 기능하는 변수의 수
C++에서 내 함수에 변수의 수를 변경할 수 있는 방법.
아날로그(C#):
public void Foo(params int[] a) {
for (int i = 0; i < a.Length; i++)
Console.WriteLine(a[i]);
}
public void UseFoo() {
Foo();
Foo(1);
Foo(1, 2);
}
Java의 아날로그:
public void Foo(int... a) {
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
}
public void UseFoo() {
Foo();
Foo(1);
Foo(2);
}
이러한 기능을 변수 함수라고 합니다.위키백과는 C++의 예제 코드를 나열합니다.
C 프로그래밍 언어에서 가변 함수를 이식 가능하게 구현하려면 표준 stdarg.h 헤더 파일을 사용해야 합니다.오래된 변수들.h 헤더는 stdarg.h를 위해 더 이상 사용되지 않습니다.C++에서는 헤더 파일을 사용해야 합니다.
변수 함수생생부를면략호려하성,▁(부(▁to호▁an
...
변수.는 매개 변수 목록의 끝에 있어야 합니다. 안에 는 본의문내부, 변의수유입니다.va_list
정의해야 합니다. 그면매크가로러▁then▁macros가▁the.va_start(va_list, last fixed param)
,va_arg(va_list, cast type)
,va_end(va_list)
사용할 수 있습니다.예:
#include <stdarg.h>
double average(int count, ...)
{
va_list ap;
int j;
double tot = 0;
va_start(ap, count); //Requires the last fixed parameter (to get the address)
for(j=0; j<count; j++)
tot+=va_arg(ap, double); //Requires the type to cast to. Increments ap to the next argument.
va_end(ap);
return tot/count;
}
실제 C++ 솔루션은 가변 템플릿입니다.상당히 최신 컴파일러가 필요하며 필요한 경우 C++11 지원을 활성화합니다.
"모든 함수 인수에 대해 동일한 작업 수행" 문제를 처리하는 두 가지 방법: 재귀적인 방법과 추악한(그러나 매우 표준을 준수하는) 솔루션입니다.
재귀적 솔루션은 다음과 같습니다.
template<typename... ArgTypes>
void print(ArgTypes... args);
template<typename T, typename... ArgTypes>
void print(T t, ArgTypes... args)
{
std::cout << t;
print(args...);
}
template<> void print() {} // end recursion
각 인수 컬렉션에 대해 하나의 기호를 생성한 다음 재귀로 들어가는 각 단계에 대해 하나씩 생성합니다.이것은 최소한으로 말하기에는 차선책입니다. 그래서 여기 SO에 있는 멋진 C++ 사람들은 목록 초기화의 부작용을 악용하는 대단한 속임수를 생각했습니다.
struct expand_type {
template<typename... T>
expand_type(T&&...) {}
};
template<typename... ArgTypes>
void print(ArgTypes... args)
{
expand_type{ 0, (std::cout << args, 0)... };
}
코드는 100만 개의 약간 다른 템플릿 인스턴스에 대해 생성되지 않으며, 보너스로 함수 인수의 보존 순서를 얻을 수 있습니다.이 솔루션에 대한 자세한 내용은 다른 답변을 참조하십시오.
C++11 이상에서는 이니셜라이저 목록도 사용할 수 있습니다.
int sum(const initializer_list<int> &il)
{
int nSum = 0;
for (auto x: il)
nSum += x;
return nsum;
}
cout << sum( { 3, 4, 6, 9 } );
다른 답은 차치하고, 정수 배열을 전달하려는 경우에는 다음과 같이 하십시오.
void func(const std::vector<int>& p)
{
// ...
}
std::vector<int> params;
params.push_back(1);
params.push_back(2);
params.push_back(3);
func(params);
하지만 매개 변수로 부를 수는 없습니다.답변에 나열된 변수 함수를 사용해야 합니다.C++0x는 가변 템플릿을 사용할 수 있으므로 유형이 안전하지만, 현재로서는 기본적으로 메모리와 캐스팅입니다.
일종의 변수 매개 변수->벡터 같은 것을 에뮬레이트할 수 있습니다.
// would also want to allow specifying the allocator, for completeness
template <typename T>
std::vector<T> gen_vec(void)
{
std::vector<T> result(0);
return result;
}
template <typename T>
std::vector<T> gen_vec(T a1)
{
std::vector<T> result(1);
result.push_back(a1);
return result;
}
template <typename T>
std::vector<T> gen_vec(T a1, T a2)
{
std::vector<T> result(1);
result.push_back(a1);
result.push_back(a2);
return result;
}
template <typename T>
std::vector<T> gen_vec(T a1, T a2, T a3)
{
std::vector<T> result(1);
result.push_back(a1);
result.push_back(a2);
result.push_back(a3);
return result;
}
// and so on, boost stops at nine by default for their variadic templates
용도:
func(gen_vec(1,2,3));
C, Objective-C, C++ 및 D의 변수 함수 참조
stdarg.h를 포함하고 다음을 사용해야 합니다.va_list
,va_start
,va_arg
그리고.va_end
위키백과 기사의 예에서 알 수 있듯이.C와 C++는 변수에 대한 제한된 내장 지원만 있기 때문에 Java나 C#보다 조금 더 번거롭습니다.
휴대성에 관심이 없다면 gcc의 문 표현식을 사용하여 이 C99 코드를 C++로 포팅할 수 있습니다.
#include <cstdio>
int _sum(size_t count, int values[])
{
int s = 0;
while(count--) s += values[count];
return s;
}
#define sum(...) ({ \
int _sum_args[] = { __VA_ARGS__ }; \
_sum(sizeof _sum_args / sizeof *_sum_args, _sum_args); \
})
int main(void)
{
std::printf("%i", sum(1, 2, 3));
}
C++0x' 람다 식으로 비슷한 것을 할 수 있지만, 제가 사용하는 gcc 버전(4.4.0)은 지원하지 않습니다.
GManNickG 및 Christoph 답변은 좋지만, 변수 함수를 사용하면 정수뿐만 아니라 원하는 대로 ... 매개 변수를 밀어넣을 수 있습니다.변수 함수가 너무 어렵거나 복잡하거나 사용 방법이 마음에 들지 않거나 사용에 필요한 헤더를 포함하지 않기 때문에 나중에 변수 함수를 사용하지 않고 다른 유형의 많은 변수와 값을 함수에 밀어넣으려면 항상 매개 변수를 사용할 수 있습니다.
예를 들어 Stephan202는 다음과 같이 게시했습니다.
double average(int count, ...)
{
va_list ap;
int j;
double tot = 0;
va_start(ap, count); //Requires the last fixed parameter (to get the address)
for(j=0; j<count; j++)
tot+=va_arg(ap, double); //Requires the type to cast to. Increments ap to the next argument.
va_end(ap);
return tot/count;
}
이는 다음과 같이 쓸 수도 있습니다.
double average(int count, void** params)
{
int j;
double tot = 0;
for (j=0; j<count; j++)
tot+=*(double*)params[j];
return tot/count;
}
이제 다음과 같이 사용합니다.
int _tmain(int argc, _TCHAR* argv[])
{
void** params = new void*[3];
double p1 = 1, p2 = 2, p3 = 3;
params[0] = &p1;
params[1] = &p2;
params[2] = &p3;
printf("Average is: %g\n", average(3, params));
system("pause");
return 0;
}
전체 코드:
#include "stdafx"
#include <process.h>
double average(int count, void** params)
{
int j;
double tot = 0;
for (j=0; j<count; j++)
tot+=*(double*)params[j];
return tot/count;
}
int _tmain(int argc, _TCHAR* argv[])
{
void** params = new void*[3];
double p1 = 1, p2 = 2, p3 = 3;
params[0] = &p1;
params[1] = &p2;
params[2] = &p3;
printf("Average is: %g\n", average(3, params));
system("pause");
return 0;
}
출력:
평균: 2
계속하려면 아무 키나 누르십시오.
나는 c++ builder xe에서 이렇게 내 것을 합니다.xx:
String s[] = {"hello ", " unli", " param", " test"};
String ret = BuildList(s, 4);
String BuildList(String s[], int count)
{
for(int i = 0; i < count; i++)
{
//.... loop here up to last s[i] item ...
}
}
언급URL : https://stackoverflow.com/questions/1579719/variable-number-of-parameters-in-function-in-c
'programing' 카테고리의 다른 글
뒤에 코드가 없는 ASP.net 페이지 (0) | 2023.06.15 |
---|---|
플롯 축 값 제거 (0) | 2023.06.15 |
포인터 유형을 선언하시겠습니까? (0) | 2023.06.15 |
인식할 수 없는 특성 'targetFramework'입니다.속성 이름은 대소문자를 구분합니다. (0) | 2023.06.15 |
NgFor가 Angular2의 파이프로 데이터를 업데이트하지 않습니다. (0) | 2023.06.15 |