2013-04-26 103 views
0

是否可以定义一个接受如下表达式的宏:object.method()?我想制作一个宏,将该表达式改变为...没有任何东西(删除它)。只用function()我会这样做:#define function(没有任何价值),但是有可能创建一个带点的宏吗?带点的预处理器宏?

编辑:关于MooingDuck的评论:

object.Method("text", "other"); 

定义:

void Class::Method(std::string arg1, std::string arg2) 
{ 
#if 0 
    if (condition) 
    { 
     Method2(arg1, arg2); 
    } 
#endif 
} 

拆卸:

object.Method("text", "other"); 
00394396 mov   edi,5 
0039439B mov   eax,offset string "other" (396348h) 
003943A0 lea   esi,[ebp-4Ch] 
003943A3 mov   dword ptr [ebp-38h],0Fh 
003943AA mov   dword ptr [ebp-3Ch],ebx 
003943AD mov   byte ptr [ebp-4Ch],bl 
003943B0 call  std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign (393360h) 
003943B5 mov   dword ptr [ebp-4],1 
003943BC mov   edi,4 
003943C1 mov   eax,offset string "text" (396350h) 
003943C6 lea   esi,[ebp-30h] 
003943C9 mov   dword ptr [ebp-1Ch],0Fh 
003943D0 mov   dword ptr [ebp-20h],ebx 
003943D3 mov   byte ptr [ebp-30h],bl 
003943D6 call  std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign (393360h) 
003943DB mov   esi,10h 
003943E0 mov   dword ptr [ebp-4],0FFFFFFFFh 
003943E7 cmp   dword ptr [ebp-1Ch],esi 
003943EA jb   main+0B9h (3943F9h) 
003943EC mov   eax,dword ptr [ebp-30h] 
003943EF push  eax 
003943F0 call  dword ptr [__imp_operator delete (3960ECh)] 
003943F6 add   esp,4 
003943F9 mov   edi,0Fh 
003943FE mov   dword ptr [ebp-1Ch],edi 
00394401 mov   dword ptr [ebp-20h],ebx 
00394404 mov   byte ptr [ebp-30h],bl 
00394407 cmp   dword ptr [ebp-38h],esi 
0039440A jb   main+0D9h (394419h) 
0039440C mov   ecx,dword ptr [ebp-4Ch] 
0039440F push  ecx 
00394410 call  dword ptr [__imp_operator delete (3960ECh)] 
00394416 add   esp,4 
+0

对于这样的事情,你可以使用'#ifdef' /'#endif'构造。对此使用宏几乎肯定是一个坏主意(如果甚至可能的话)。你究竟想要解决什么问题? – 2013-04-26 00:40:46

+1

宏名称必须是标识符;它不能包含'.'字符。 – 2013-04-26 00:41:32

+0

对于*任何*名称的方法?或者为一组特定的命名方法? – 2013-04-26 00:49:54

回答

3

你的代码是:

void Class::Method(const std::string& arg1, const std::string& arg2) 
{ 
#if 0 
    if (condition) 
    { 
     Method2(arg1, arg2); 
    } 
#endif 
} 

但问题是,当你调用此方法,字符串常量,它仍然是构建std::string对象,因为他们建造的过程中可能有副作用。

我想我会试试这个,直到函数内部才会进行转换,因此编译器也可以忽略std::string构造。

template<class arg1_t, class arg2_t> 
void Class::Method(const arg1_t& arg1, const arg2_t& arg2) 
{ 
#if 0 
    if (condition) 
    { 
     Method2(arg1, arg2); 
    } 
#endif 
} 
+0

工作,谢谢。我有不同的解决方案,但这个更好,因为它只允许我的类的方法被忽略。但它仍然依赖编译器优化(摆脱)方法的能力。但那是我不会避免的。或者我会吗? – NPS 2013-04-26 22:36:21

+0

总有'#define方法(X,Y)方法',但我真的不建议这样做。 – 2013-04-27 00:46:37

+0

为什么不实际? – NPS 2013-04-27 06:59:29

1

宏的名称是一个标识符。没有办法。

不同的编译器可能允许不同的字符到标识符中(如$),但它们都不允许.。在一天结束时,C预处理器被设计成一个“轻量级预处理器”,并不像其他更强大的预处理器一样,在80年代中期存在,而不是用于幻想转换。

虽然你可以做这样的事情(不是真的推荐):

struct DoNothing 
{ 
    void method() { } 
}; 

DoNothing g_inst; 

#define object g_inst 

几乎可以肯定的宏生成的代码将被优化完全去除。这种方法对所有使用的名称都很敏感。一切都应该明确提及。