변수 인수 목록을 허용하는 다른 함수에 변수 인수 전달
그래서 나는 둘 다 비슷한 인수를 갖는 두 개의 함수를 가지고 있습니다.
void example(int a, int b, ...);
void exampleB(int b, ...);
이제를 example
호출 exampleB
하지만 수정하지 않고 변수 인수 목록의 변수를 어떻게 전달할 수 있습니까 exampleB
(이미 다른 곳에서도 사용됨).
직접 할 수는 없습니다. 다음을받는 함수를 만들어야합니다 va_list
.
#include <stdarg.h>
static void exampleV(int b, va_list args);
void exampleA(int a, int b, ...) // Renamed for consistency
{
va_list args;
do_something(a); // Use argument a somehow
va_start(args, b);
exampleV(b, args);
va_end(args);
}
void exampleB(int b, ...)
{
va_list args;
va_start(args, b);
exampleV(b, args);
va_end(args);
}
static void exampleV(int b, va_list args)
{
...whatever you planned to have exampleB do...
...except it calls neither va_start nor va_end...
}
여기 연못에 바위를 던질 수도 있지만 C ++ 11 가변 템플릿으로 꽤 잘 작동하는 것 같습니다.
#include <stdio.h>
template<typename... Args> void test(const char * f, Args... args) {
printf(f, args...);
}
int main()
{
int a = 2;
test("%s\n", "test");
test("%s %d %d %p\n", "second test", 2, a, &a);
}
최소한 g++
.
va_list를 받아 전달하는 이러한 함수의 버전을 만들어야합니다. 봐 vprintf
예를 들어 :
int vprintf ( const char * format, va_list arg );
또한 printf를 래핑하고 여기에서 유용한 답변을 찾았습니다.
가변 개수의 인수를 printf / sprintf에 전달하는 방법
I was not at all interested in performance (I'm sure this piece of code can be improved in a number of ways, feel free to do so :) ), this is for general debugprinting only so I did this:
//Helper function
std::string osprintf(const char *fmt, ...)
{
va_list args;
char buf[1000];
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args );
va_end(args);
return buf;
}
which I then can use like this
Point2d p;
cout << osprintf("Point2d: (%3i, %3i)", p.x, p.y);
instead of for example:
cout << "Point2d: ( " << setw(3) << p.x << ", " << p.y << " )";
The c++ ostreams are beautiful in some aspects, but practically the become horrific if you want to print something like this with some small strings such as parenthesis, colons and commas inserted between the numbers.
Incidentally, many C implementations have an internal v?printf variation which IMHO should have been part of the C standard. The exact details vary, but a typical implementation will accept a struct containing a character-output function pointer and information saying what's supposed to happen. This allows printf, sprintf, and fprintf to all use the same 'core' mechanism. For example, vsprintf might be something like:
void s_out(PRINTF_INFO *p_inf, char ch) { (*(p_inf->destptr)++) = ch; p_inf->result++; } int vsprintf(char *dest, const char *fmt, va_list args) { PRINTF_INFO p_inf; p_inf.destptr = dest; p_inf.result = 0; p_inf.func = s_out; core_printf(&p_inf,fmt,args); }
The core_printf function then calls p_inf->func for each character to be output; the output function can then send the characters to the console, a file, a string, or something else. If one's implementation exposes the core_printf function (and whatever setup mechanism it uses) one can extend it with all sorts of variations.
Based on the comment that you're wrapping vsprintf
, and that this is tagged as C++ I'd suggest not trying to do this, but change up your interface to use C++ iostreams instead. They have advantages over the print
line of functions, such as type safety and being able to print items that printf
wouldn't be able to handle. Some rework now could save a significant amount of pain in the future.
A possible way is to use #define:
#define exampleB(int b, ...) example(0, b, __VA_ARGS__)
Using the new C++0x standard, you may be able to get this done using variadic templates or even convert that old code to the new template syntax without breaking anything.
'programing tip' 카테고리의 다른 글
일시적으로 Eclipse 플러그인 비활성화 (0) | 2020.08.27 |
---|---|
팹을 언제 사용하고 std :: abs를 사용하기에 충분합니까? (0) | 2020.08.27 |
파일 린트의“너무 적은 공개 방법”메시지는 무엇을 의미합니까? (0) | 2020.08.27 |
Mercurial을 사용하면 푸시하기 전에 일련의 변경 세트를 하나로 "압축"할 수 있습니까? (0) | 2020.08.27 |
자바 스크립트에서 특정 오류 처리 (예외를 생각해보세요) (0) | 2020.08.27 |