如何检索整个va_list输入

时间:2012-04-09 07:10:58

标签: c++ c visual-c++

我熟悉va_arg列表。我想知道有没有办法在逗号

之后获取值

例如

abc("%d %d %d how are you",1,2,3);

我想知道是否可以将整个调用传递给字符串而不进行任何处理,如

string [1]="%d %d %d how are you",1,2,3;

我不想做任何处理,我只是想读取整个调用并将其存储在一个数组字符串中。

3 个答案:

答案 0 :(得分:2)

尽管我能理解你的要求,但在标准C ++ 03中是不可能的。最密切相关的C ++功能是预处理器宏参数字符串化,它允许这样的事情:

#define ABC(X) do { remember_string_version(#X); abc X; } while (false)

ABC(("%d %d %d how are you",1,2,3));

请注意双括号 - 这些字符串和数字组合使它们与ABC预期的单个参数“X”匹配。

预处理程序字符串化是唯一的工具,它允许您将一些源代码片段保存为字符串,同时仍将其用作源代码....

答案 1 :(得分:0)

这是依赖于编译器的,虽然理论上你可以这样做,但实际上它可能不是可移植的。您可以在编译时通过宏执行此操作,如@Tony所述,但对于运行时 - 使用va_arg。它基本上实现了你想要的东西,并且是标准提供的工具,用于连接这个依赖于编译器的功能。

答案 2 :(得分:0)

从C ++ 17开始,您可以捕获所有参数并将它们转发到单个表达式中的字符串流(称为 fold-expression ):

#include <string>
#include <sstream>
#include <iostream>
#include <functional>

std::string abc(auto&& head, auto&&... tail)
{
    std::ostringstream out;
    out << head;
    ((out << ',' << tail), ...);

    return out.str();
}

int main()
{
    std::string s = abc("%d %d %d how are you", 1, 2, 3);

    std::cout << s << std::endl;
}

在C ++ 17之前,但是从C ++ 11开始,你可以使用一个递归模板(或者我将不会在这里讨论的void braced list hack)。片段:

template<typename Head>
void capture(std::ostream& out, Head&& head)
{
    out << std::forward<Head>(head);
}

template<typename Head, typename... Tail>
void capture(std::ostream& out, Head&& head, Tail&&... tail)
{
    out << std::forward<Head>(head) << ',';
    capture(out, std::forward<Tail>(tail)...);
}

template<typename... Args>
std::string abc(Args&&... args)
{
    std::ostringstream out;
    capture(out, std::forward<Args>(args)...);

    return out.str();    
}