是否有可能创建宏来替换operator new
包含额外args的所有形式的重载...说__FILE__
和__LINE__
?
麻烦似乎operator new
可以用括号括或不用括号编码,因此:
类似对象的宏:
#define new new(__FILE__, __LINE__)
Run Code Online (Sandbox Code Playgroud)
将取代声明,如:
A* a = new A();
Run Code Online (Sandbox Code Playgroud)和类似函数的宏:
#define new(A) new (A, __FILE__, __LINE__)
Run Code Online (Sandbox Code Playgroud)
将取代声明,如:
A* a = new(std::nothrow) A();
Run Code Online (Sandbox Code Playgroud)不幸的是,尝试使用相同的标识符声明两个宏是错误的,即使它们的类型不同,因此以下操作失败:
#define new new(__FILE__, __LINE__)
#define new(A) new (A, __FILE__, __LINE__) // Error: "new" already defined
Run Code Online (Sandbox Code Playgroud)
由于我正在使用g ++,我希望使用它们的可变参数宏的语法会产生成功,但遗憾的是没有.下列:
#define new(...) new(__FILE__, __LINE__, ## __VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
只匹配new(xyx) A()
,而不是new A()
.
我想做这样的事情:
class SomeClass { };
GENERATE_FUNTION(SomeClass)
Run Code Online (Sandbox Code Playgroud)
该GENERATE_FUNCTION
宏我想定义的名字是由宏参数确定的函数.在这种情况下,我希望它定义一个函数func_SomeClass
.怎么办?
我正在看一个定义了大量常量数组的应用程序.让我感到困惑的是在宏观中使用彼此相邻的两个磅标志.例如:
#define r0(p,q,r,s) 0x##p##q##r##s
Run Code Online (Sandbox Code Playgroud)
那两个磅标志是什么意思?
例如,永远不要像这样定义一个宏:
#define DANGER 60 + 2
Run Code Online (Sandbox Code Playgroud)
当我们执行这样的操作时,这可能是危险的:
int wrong_value = DANGER * 2; // Expecting 124
Run Code Online (Sandbox Code Playgroud)
相反,定义这样,因为你不知道宏的用户如何使用它:
#define HARMLESS (60 + 2)
Run Code Online (Sandbox Code Playgroud)
这个例子很简单,但这几乎解释了我的问题.在编写宏时,您会建议使用哪些指南或最佳实践吗?
谢谢你的时间!
是否可以编写一个返回其参数数量的C宏?
我想做的事情:
foo(1) -> 1
foo(cat, dog) -> 2
foo(red, green, blue) -> 3
Run Code Online (Sandbox Code Playgroud)
如果可以以这样的方式定义这个宏以便它与##一起工作,那就更好了
foo(1) -> bar1(1)
foo(cat, dog) -> bar2(cat, dog)
foo(red, green, blue) -> car3(red, green, blue)
Run Code Online (Sandbox Code Playgroud)
谢谢!
编辑:我真的想要一个宏,而不是一个函数.使用功能的建议将被低估.
所以我有一个在GCC中运行良好的宏,但在微软的C++编译器中没有.我希望有人可能知道一种解决方法,或者也许可以向我解释它为什么会这样.
我确定这个宏并不完全是"标准",但它确实会帮助我.
这是宏的一个功能示例:
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)
#define FULLY_EXPANDED(count, ...) \
MAC ## count (__VA_ARGS__)
#define SEMI_EXPANDED(count, ...) FULLY_EXPANDED(count, __VA_ARGS__)
#define EXPAND_THESE(...) SEMI_EXPANDED(VA_NARGS(__VA_ARGS__), __VA_ARGS__)
#define ACTUAL_MACRO(x) parent->GetProperty<x>();
#define MAC1(a) ACTUAL_MACRO(a)
#define MAC2(a,b) MAC1(a) ACTUAL_MACRO(b)
#define MAC3(a,b,c) MAC2(a,b) ACTUAL_MACRO(c)
#define MAC4(a,b,c,d) MAC3(a,b,c) ACTUAL_MACRO(d)
#define MAC5(a,b,c,d,e) MAC4(a,b,c,d) ACTUAL_MACRO(e)
Run Code Online (Sandbox Code Playgroud)
以下是我如何使用此宏:
struct MyStructure
{
void Foo()
{
EXPAND_THESE(Property1, Property2, Property3, Property4)
}
Base * parent;
}
Run Code Online (Sandbox Code Playgroud)
以下是GCC如何扩展上述内容:
struct MyStructure
{
void …
Run Code Online (Sandbox Code Playgroud) 我正在尝试定义一个宏,假设它采用2个字符串值并返回它们之间的一个空格连接.似乎我可以使用除空间之外我想要的任何角色,例如:
#define conc(str1,str2) #str1 ## #str2
#define space_conc(str1,str2) conc(str1,-) ## #str2
space_conc(idan,oop);
Run Code Online (Sandbox Code Playgroud)
space_conc
将返回"idan-oop"
我想要一些东西回归"idan oop",建议?
我正在尝试构建一个调试日志消息函数,该函数记录调用日志消息的位置的文件,行和函数.
#define DEBUG_PANIC(p) CLogging::Debuglogf( "Debug marker (%s) - ::%s() in file: %s(%d)", p, __func__ , __FILE__, __LINE__ );
Run Code Online (Sandbox Code Playgroud)
上面的代码适用于某些编译器,但不是全部.我的代码需要与GCC以及Microsoft Visual工作室交叉兼容.我已添加以下定义以帮助兼容性.
#ifndef __FUNCTION_NAME__
#if defined __func__
// Undeclared
#define __FUNCTION_NAME__ __func__
#elif defined __FUNCTION__
// Undeclared
#define __FUNCTION_NAME__ __FUNCTION__
#elif defined __PRETTY_FUNCTION__
// Undeclared
#define __FUNCTION_NAME__ __PRETTY_FUNCTION__
#else
// Declared
#define __FUNCTION_NAME__ "N/A"
#endif // __func__
#endif // __FUNCTION_NAME__
#define DEBUG_PANIC(p) CLogging::Debuglogf( "Debug marker (%s) - ::%s() in file: %s(%d)", p, __FUNCTION_NAME__, __FILE__, __LINE__ );
Run Code Online (Sandbox Code Playgroud)
上面代码片段的问题在于#else宏在所有编译器上都处于活动状态,而其他宏则没有.换句话说#if defined __func__
,在编译器上是假的,其中__func__ …
我想使用宏字符串化声明内联的GLSL着色器字符串:
#define STRINGIFY(A) #A
const GLchar* vert = STRINGIFY(
#version 120\n
attribute vec2 position;
void main()
{
gl_Position = vec4( position, 0.0, 1.0 );
}
);
Run Code Online (Sandbox Code Playgroud)
这使用VS2010构建并运行良好,但无法编译gcc
:
error: invalid preprocessing directive #version
Run Code Online (Sandbox Code Playgroud)
有没有办法以可移植的方式使用这样的字符串化?
我试图避免每行引用:
const GLchar* vert =
"#version 120\n"
"attribute vec2 position;"
"void main()"
"{"
" gl_Position = vec4( position, 0.0, 1.0 );"
"}"
;
Run Code Online (Sandbox Code Playgroud)
......和/或续行:
const GLchar* vert = "\
#version 120\n \
attribute vec2 position; \
void main() \
{ \
gl_Position = vec4( position, …
Run Code Online (Sandbox Code Playgroud) 我得到了以下实现来获取可变参数宏中的参数数量(目前限制为16个参数).但是,对于VS2010 1
,无论传递多少个参数,输出总是如此.使用GCC,输出是正确的,让我得出结论,我必须错过MSVC特有的东西(10).
#define PP_NARGS(...) \
_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#define _xPP_NARGS_IMPL(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) N
int main(){
int i = PP_NARGS(A,V,C,X,Y,Z);
std::cout << i;
std::cin.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
因此,问题是标题所述,任何帮助将不胜感激.