繁体   English   中英

C ++函数可打印任意数量的参数

[英]C++ Function to print any number of arguments

我在下面用C ++编写了此函数。 使用任意数量的参数调用函数trace()以格式显示每个参数的值以及参数名

名称1:值1 | name2:value2,依此类推。

我想学习这段代码是如何工作的,以及像&&__VA_ARGS__这样的一些语法的含义。 谢谢!

#define tr(...) trace(#__VA_ARGS__, __VA_ARGS__)

template <typename Arg1>
void trace(const char* name, Arg1&& arg1){
    cout << name << " : " << arg1 << endl;
}

template <typename Arg1, typename... Args>
void trace(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');
    cout.write(names, comma-names) << " : " << arg1 << " | " ; 

    trace(comma+1, args...);
}
#define tr(...) trace(#__VA_ARGS__, __VA_ARGS__)

是一个函数宏,它接受可变数量的参数。
它转发一个字符串化的版本作为第一个参数。
如果不使用预处理程序,则无法派生字符串表示形式。

评估示例:

int main(){
    int i;
    float f;
    std::string s;
    tr(i,f,s);
}

解析为:

int main(){
    int i;
    float f;
    std::string s;
    trace("i,f,s", i,f,s);
}

这两个可变参数模板函数展开每个参数,然后递归调用自身。

结束递归的基本情况函数是:

template <typename Arg1>
void trace(const char* name, Arg1&& arg1){
    cout << name << " : " << arg1 << endl;
}

fold表达式可以更加干净地完成。

&&用于实现完美的转发。

此功能取决于多种机制:

  • 可变参数模板 :为了支持任意数量的参数,该函数定义为可变参数模板。 此功能具有递归语法,就像您在功能性语言中可能遇到的那样: template <typename Arg1, typename... Args> ,其中Arg1是第一个参数,而Args是所有其余Args 因此,函数本身的递归定义-为了解压缩参数,它调用自身作为参数列表的末尾部分。 请注意comma-names技巧,以计算参数名称的长度。
  • 预处理程序字符串化运算符__VA_ARGS__当然只是tr(...) (逗号分隔)的参数列表的宏。 在它之前添加#是从中创建字符串的方式,该字符串作为trace(const char* names, ...)的第一个参数传递。
  • 参考崩溃 (模板中的Arg &&):这实际上是这里最复杂的事情,令人遗憾的是,因为它几乎什么也没做。 您可以从字面上删除&& s,并且代码仍将按预期运行。 &&的作用是调整期望参数的引用类型以匹配实际传递的内容,例如,如果您按引用传递参数,则不会复制它;如果传递临时对象,它将使用move语义。 这个功能的实现技术很难说,因此这是另一个SO问题,需要进一步阅读

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM