簡體   English   中英

鏈接可變參數函數調用

[英]chaining variadic function calls

從具有可變參數數目的函數進行的類似於printf函數的調用非常容易進行-只需使用這些函數的v版本vprintfvsprintfCString::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM