[英]chaining variadic function calls
從具有可變參數數目的函數進行的類似於printf
函數的調用非常容易進行-只需使用這些函數的v版本 ( vprintf
, vsprintf
, CString::FormatV
等)即可。 但是,如果我將呼叫鏈接起來怎么辦? 這是簡單的代碼:
#include <stdarg.h>
#include <iostream>
void direct(const char * _fmt, bool _extra, ...){
va_list args;
va_start(args, _extra);
char ca[200];
vsprintf(ca, _fmt, args);
std::cout << ca << std::endl;
va_end(args);
}
void chained(const char * _fmt, ...){
va_list args;
va_start(args, _fmt);
direct(_fmt, false, args);
va_end(args);
}
int main(){
direct("direct works just fine: %d", false, 1);
chained("indirect produces garbage: %d", 1);
return 0;
}
示例輸出如下:
direct works just fine: 1
indirect produces garbage: 1951661256
我覺得我缺少明顯的東西,但到目前為止還不能弄清楚。 請幫助我修復它,以便無論我direct
調用還是chained
代碼都可以正常工作。
將問題標記為C / C ++,但我更喜歡C ++答案(如果有所不同)
我覺得我遺漏了一些明顯的東西,但到目前為止還無法弄清楚
你做到了 這實際上是您開始的: “僅使用這些函數的v版本” 。 這些函數獲得v版本的原因是允許將它們鏈接起來,就像您所說的那樣。 因此,如果要為自己的類似於printf的功能支持它,請確保遵循相同的做法:
void direct_v(const char * _fmt, bool _extra, va_list args){
char ca[200];
vsprintf(ca, _fmt, args);
std::cout << ca << std::endl;
}
void direct(const char * _fmt, bool _extra...){
va_list args;
va_start(args, _extra);
direct_v(_fmt, _extra, args);
va_end(args);
}
void chained(const char * _fmt...){
va_list args;
va_start(args, _fmt);
direct_v(_fmt, false, args);
va_end(args);
}
這樣direct
拆分的一個很好的新興特性是,您可以更好地分離關注點。 包裝器執行與va_list
相關的位,而v函數僅關心列表需要完成的操作,因此可以在此處重用。
編輯前注意:順便說一句,如果確實需要C兼容性,則函數原型需要使用逗號將最后一個參數與省略號分開。 您使用的語法僅是C ++。
您不能將調用鏈接到C樣式可變參數函數。 唯一的方法是將va_list
作為參數傳遞。 這正是需要v *系列功能的原因。
因此,您可以使用va_list
編寫va_list
v *的函數, 然后將每個函數包裝在基於省略號的可變參數中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.