C/C++__VA_ARGS__学习--自动打印函数的参数和返回值

C/C++__VA_ARGS__学习--自动打印函数的参数和返回值

  • 一.参考
  • 二.输出
  • 三.代码

通过__VA_ARGS__,自动打印函数的参数和返回值

一.参考

  • c/c++:提取可变参数宏__VA_ARGS__中偶数位置参数

二.输出

input:A StructA= StructA[1,2,3,4,10,11,12,13,]
input:B StructB*= StructB[26,27,28,29,StructA[1,2,3,4,10,11,12,13,]]
input:C int= 1000
input:D float= 2000.2
output:ret "StructA"= StructA[101,2,3,4,10,11,12,13,]

三.代码

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#include <iostream>
#include <string>
#include <algorithm>

#define IDENTITY(x) x
#define FL_CONCAT(x, y) x##y

// 计算 __VA_ARGS__ 参数个数,最大支持64个参数 https://blog.csdn.net/10km/article/details/80769615
#define FL_TYPEVALUES_COUNT(...) FL_INTERNAL_ARG_COUNT_PRIVATE(0, ##__VA_ARGS__,\
	64, 63, 62, 61, 60, \
	59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
	49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
	39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \
	29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
	19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
	 9,  8,  7,  6,  5,  4,  3,  2,  1,  0)

#define FL_INTERNAL_ARG_COUNT_PRIVATE(\
	 _0,  _1,  _2,  _3,  _4,  _5,  _6,  _7,  _8,  _9, \
	_10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \
	_20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \
	_30, _31, _32, _33, _34, _35, _36, _37, _38, _39, \
	_40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \
	_50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \
	_60, _61, _62, _63, _64, N, ...) N
					   
#define FL_TYPEVALUES0()
#define FL_TYPEVALUES2(t, v) t v
#define FL_TYPEVALUES4(t, v, ...)        FL_TYPEVALUES2(t, v), IDENTITY(FL_TYPEVALUES2(__VA_ARGS__))
#define FL_TYPEVALUES6(t, v, ...)        FL_TYPEVALUES2(t, v), IDENTITY(FL_TYPEVALUES4(__VA_ARGS__))
#define FL_TYPEVALUES8(t, v, ...)        FL_TYPEVALUES2(t, v), IDENTITY(FL_TYPEVALUES6(__VA_ARGS__))
#define FL_TYPEVALUES10(t, v, ...)       FL_TYPEVALUES2(t, v), IDENTITY(FL_TYPEVALUES8(__VA_ARGS__))

#define FL_VALUES_0()
#define FL_VALUES_2(t, v) v
#define FL_VALUES_4(t, v, ...)           FL_VALUES_2(t, v), FL_VALUES_2(__VA_ARGS__)
#define FL_VALUES_6(t, v, ...)           FL_VALUES_2(t, v), FL_VALUES_4(__VA_ARGS__)
#define FL_VALUES_8(t, v, ...)           FL_VALUES_2(t, v), FL_VALUES_6(__VA_ARGS__)
#define FL_VALUES_10(t, v, ...)          FL_VALUES_2(t, v), FL_VALUES_8(__VA_ARGS__)
#define FL_VALUES_12(t, v, ...)          FL_VALUES_2(t, v), FL_VALUES_10(__VA_ARGS__)  
  
#define FL_TYPEVALUES__(count, ...)      IDENTITY(FL_CONCAT(FL_TYPEVALUES, count)(__VA_ARGS__))
#define FL_TYPEVALUES_(count, ...)       FL_TYPEVALUES__(count, __VA_ARGS__)
#define FL_TYPEVALUES(...)               FL_TYPEVALUES_(FL_TYPEVALUES_COUNT(__VA_ARGS__), __VA_ARGS__)
  
#define FL_VALUES__(count, ...)          FL_VALUES_##count(__VA_ARGS__)
#define FL_VALUES_(count, ...)           FL_VALUES__(count, __VA_ARGS__)
#define FL_VALUES(...)                   FL_VALUES_(FL_TYPEVALUES_COUNT(__VA_ARGS__), __VA_ARGS__)

template <typename T>
void PRINT_V(T name) {
  std::cout << name;
}
  
template <typename T>
void PRINT_V(T* name) {
  std::cout << *name;
}   
  
#define PRINT_ARGS2(t, v)                           \
  printf("input:%s %s= ",#v, #t);                   \
  PRINT_V(v);                                       \
  printf("\n");                                     \
  fflush(stdout);
 
#define PRINT_ARGS4(t, v, ...)           PRINT_ARGS2(t, v) PRINT_ARGS2(__VA_ARGS__)
#define PRINT_ARGS6(t, v, ...)           PRINT_ARGS2(t, v) PRINT_ARGS4(__VA_ARGS__)
#define PRINT_ARGS8(t, v, ...)           PRINT_ARGS2(t, v) PRINT_ARGS6(__VA_ARGS__)
#define PRINT_ARGS10(t, v, ...)          PRINT_ARGS2(t, v) PRINT_ARGS8(__VA_ARGS__)
#define PRINT_ARGS12(t, v, ...)          PRINT_ARGS2(t, v) PRINT_ARGS10(__VA_ARGS__)
  
#define PRINT_ARGS__(count, ...)         PRINT_ARGS##count(__VA_ARGS__)
#define PRINT_ARGS_(count, ...)          PRINT_ARGS__(count, __VA_ARGS__)
#define PRINT_ARGS(...)                  PRINT_ARGS_(FL_TYPEVALUES_COUNT(__VA_ARGS__), __VA_ARGS__)

#define PRINT_RET(t, v)                  printf("output:%s %s= ",#v, #t); PRINT_V(v); printf("\n"); fflush(stdout);
  
#define SDK_PROXY(t, name, ...)                       \
  t internal_##name(FL_TYPEVALUES(__VA_ARGS__));      \
  t name(FL_TYPEVALUES(__VA_ARGS__)) {                \
	PRINT_ARGS(__VA_ARGS__);                          \
    t ret = internal_##name(FL_VALUES(__VA_ARGS__));  \
	PRINT_RET(#t, ret);                               \
    return ret;                                       \
  }                                                   \
  t internal_##name(FL_TYPEVALUES(__VA_ARGS__))

struct StructA
{
	int     A;
	char    B;
	float   C;
	char*   D;
	int     E[4];
	friend std::ostream & operator<<(std::ostream &out, StructA &A)
	{
		out << "StructA["<<A.A <<","<< A.B<<","<<A.C<<","<<A.D<<",";
		std::for_each(std::begin(A.E),
			std::end(A.E),
			[](const int &e) {
				std::cout << e << ",";
			});
		out<<"]";
		return out;
	}	
};

struct StructB
{
	int      A[4];
	StructA  B;
	friend std::ostream & operator<<(std::ostream &out, StructB &A)
	{
		out << "StructB[";
		std::for_each(std::begin(A.A),
			std::end(A.A),
			[](const int &e) {
				std::cout << e << ",";
			});
		out<< A.B<<"]";
		return out;
	}
};

StructA user_api(StructA A,StructB* B);

SDK_PROXY(StructA, user_api,StructA,A,StructB*,B,int,C,float,D)
{
	StructA ret=A;
	ret.A+=100;	
    return ret;
}

int main(int argc,char*argv[])
{
	StructA A;
	StructB B;
	A.A=1;
	A.B='2';
	A.C=3.0;
	A.D="4";
	int array0[]={10,11,12,13};
	std::copy(std::begin(array0), std::end(array0), std::begin(A.E));
	
	B.B=A;
	int array1[]={26,27,28,29};
	std::copy(std::begin(array1), std::end(array1), std::begin(B.A));
	
	StructA ret=user_api(A,&B,1000,2000.2);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/607232.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NeRF算法

目录 算法介绍 基本原理 1. 体渲染 2. 多层感知机&#xff08;MLP&#xff09; 3. 位置编码 4. 两阶段层次化体采样 实验展示 代码解析 算法介绍 NeRF&#xff08;Neural Radiance Fields&#xff09;是一种用于从2D图像中重建3D场景的神经网络模型。它通过训练一个深度…

sourceTree push失败

新电脑选择commit and push&#xff0c;报错了&#xff0c;不过commit成功&#xff0c;只不过push失败了。 原因是这个&#xff0c;PuTTYs cache and carry on connecting. 这里的ssh选择的是 PuTTY/Plink&#xff0c;本地没有这个ssh密钥&#xff0c;改换成openSSH&#xff…

SRM系统供应链库存协同提升企业服务水平

SRM系统供应链库存协同是一种以提高供应链整体效率和竞争力为目标的管理方法。它涉及到企业与供应商之间的紧密合作&#xff0c;以实现库存优化、成本降低、风险分担和灵活响应市场变化等目标。 一、SRM供应链库存协同的概念和特点 SRM供应链库存协同是指企业与供应商之间通过…

音转文工具,9.8k star! 【送源码】

我们经常会遇到将音频转为文字的情况&#xff0c;比如在开会时录音的会议纪要、上课时录下的老师讲课内容。虽然网上也有一些在线的工具可以将音频转为文字&#xff0c;但是考虑到数据安全和费用问题&#xff0c;使用起来也不是很方便。 今天了不起给大家介绍一款开源工具——…

毕业论文应该怎么写?推荐几款ai写论文工具

时间过的好快&#xff0c;马上又到了一年一度的毕业季了&#xff0c;对于即将毕业的学生来说毕业论文是一道难过的坎&#xff0c;想到自己为了毕业论文熬的夜&#xff0c;掉的头发&#xff0c;真的深有感触。 不过虽然翟博士给大家的毕业论文设了高门槛&#xff0c;但是随着时…

python之装饰器,模块和文件操作和面向对象

1.装饰器详解(重点) 1_1 装饰器 程序运行的时候的记录 -- 日志 在实际工作中&#xff0c;python这样的东西&#xff0c;是放在服务器上运行的 日志其实就是记录下来当前程序的运行&#xff0c;协助我们定位问题 确定问题的方式&#xff08;通过日志、报错信…

宏的优缺点?C++有哪些技术替代宏?(const)权限的平移、缩小

宏的优缺点&#xff1f; 优点&#xff1a; 1.增强代码的复用性。【减少冗余代码】 2.提高性能&#xff0c;提升代码运行效率。 缺点&#xff1a; 1.不方便调试宏。&#xff08;因为预编译阶段进行了替换&#xff09; 2.导致代码可读性差&#xff0c;可维护性差&#xff0…

Java线程池(更新中)

1.线程池介绍 顾名思义&#xff0c;线程池就是管理一系列线程的资源池&#xff0c;其提供了一种限制和管理线程资源的方式。每个线程池还维护一些基本统计信息&#xff0c;例如已完成任务的数量。 总结一下使用线程池的好处&#xff1a; 降低资源消耗。通过重复利用已创建的…

猎头告诉你正确的“离职流程”

往期热门文章&#xff1a; 1&#xff0c;史上最全猎头技能资料&#xff0c;独家最新放送 2&#xff0c;互联网大厂java面试题知识库&#xff08;100万字&#xff09; 3&#xff0c;一线互联网大数据面试题知识库&#xff08;100万字&#xff09; 4&#xff0c;中国猎头公司排行…

SQL优化详解

目录 插入数据 insert的优化&#xff08;少量数据&#xff09; 批量插入 手动事务提交 主键顺序插入 插入大量数据 主键优化 数据组织方式&#xff1a; 页分裂&#xff1a; 主键顺序插入的方式&#xff1a; 主键乱序插入&#xff1a; 页合并&#xff1a; 主键设计…

HTML5/CSS3粒子效果进度条 超炫酷进度条动画源码

特效介绍 之前我已经分享了几款效果很不错的CSS3进度条插件&#xff0c;比如CSS3 Loading进度条加载动画特效、CSS3 3D进度条按钮 18款精美样式。今天我再来分享一款很有特色的HTML5/CSS3进度条应用。这款进度条插件在播放进度过程中出现粒子效果&#xff0c;就像一些小颗粒从…

二本生如何从大一准备考研!?保姆级全攻略

如果是二本大学&#xff0c;那考研确实是一个很好的机会 如果大家就有考研的打算&#xff0c;那就好好学习&#xff0c;好好学习英语&#xff0c;数学&#xff08;理工科&#xff09;和专业课&#xff0c;这些课程在考研的时候是肯定会考的 特别是英语和数学&#xff08;理工…

每日Attention学习5——Multi-Scale Channel Attention Module

模块出处 [link] [code] [WACV 21] Attentional Feature Fusion 模块名称 Multi-Scale Channel Attention Module (MS-CAM) 模块作用 通道注意力 模块结构 模块代码 import torch import torch.nn as nnclass MS_CAM(nn.Module):def __init__(self, channels64, r4):super(…

五一开始内卷前端,如何迅速的一个月内找到工作!

写在前面 五一过了代表新的一年不知不觉过了半年了&#xff0c;各位工作找到怎么样&#xff0c;有没有在工作中遇到解决不了的问题&#xff0c;这些问题后面怎么处理了呢&#xff1f; hello大家好&#xff0c;我又又又来了&#xff0c;今天纯干货&#xff0c;上班的朋友适当摸…

【SAP ME 39】SAP ME WebService超时时间设置

禁止废话&#xff0c;直接上图&#xff01;&#xff01;&#xff01; SAP技术官方说明

Dark Reader:夜间模式,启动!

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。 ——苏轼 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、介绍二、下载安装1、Chrome应用商店&#xff08;需科学&#xff09;2、第三方直链下载 三、使…

深入探索数据链路层:网络通信的基石

⭐小白苦学IT的博客主页⭐ ⭐初学者必看&#xff1a;Linux操作系统入门⭐ ⭐代码仓库&#xff1a;Linux代码仓库⭐ ❤关注我一起讨论和学习Linux系统❤ 前言 在网络通信的宏伟世界中&#xff0c;数据链路层扮演着至关重要的角色。它位于物理层和网络层之间&#xff0c;不仅直接…

HuggingFace烧钱做了一大批实验,揭示多模态大模型哪些trick真正有效

构建多模态大模型时有很多有效的trick&#xff0c;如采用交叉注意力机制融合图像信息到语言模型中&#xff0c;或直接将图像隐藏状态序列与文本嵌入序列结合输入至语言模型。 但是这些trick为什么有效&#xff0c;其计算效率如何&#xff0c;往往解释得很粗略或者或者缺乏充分…

C++ Builder XE EnumWindowsProc遍历所有窗口的名称

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { // 这里可以添加你的处理逻辑 // 例如&#xff0c;将句柄添加到列表中或者其他操作 // 这里我们仅仅输出到调试窗口 OutputDebugString(L"枚举窗口句柄: "); char windowHandle[10];…

ROS 2边学边练(45)-- 构建一个能动的机器人模型

前言 在上篇中我们搭建了一个机器人模型(其由各个关节&#xff08;joint&#xff09;和连杆&#xff08;link&#xff09;组成)&#xff0c;此篇我们会通过设置关节类型来实现机器人的活动。 在ROS中&#xff0c;关节一般有无限旋转&#xff08;continuous&#xff09;,有限旋转…
最新文章