【问题标题】:Ternary operator applies class-expanding macro to the both of operands三元运算符将类扩展宏应用于两个操作数
【发布时间】:2016-07-05 23:47:28
【问题描述】:

我使用 Microsoft Visual C++ 2010 和 Windows 7。

我有 DataDecoder 类来解码一些数据。这里是:

template< typename T >
class DataDecoder
{

private:

    T lpData;

public:

    DataDecoder() { lpData = NULL; }
    DataDecoder( T lpSource ) { lpData = (T)DecodeStaticData(lpSource); }
    ~DataDecoder() { if(lpData) free(lpData); }
    operator T() { return lpData; }
};

这个类完美地工作。我也有这个宏:

#define _STR_A(x) DataDecoder<char*>(x)

它也很完美。但是我的代码中还有另一种结构:

LPVOID lpAdditionalData = NULL;
LPSTR lpTemp = lpAdditionalData ? _STR_A("SOMEDATA") : NULL;

此时奇怪的事情开始发生。首先,我在DecodeStaticData() 中得到 NULL 参数。但这不可能是真的:_STR_A() 仅适用于有效参数。然后我决定看看反汇编:

0011843A  cmp         dword ptr [lpAdditionalData],0  
00118441  je          WinMain+172h (118462h)  
00118443  push        offset string "SOMEDATA" (124068h)  
00118448  lea         ecx,[ebp-0C2Ch]  
0011844E  call        DataDecoder<char *>::DataDecoder<char *> (117770h)  
00118453  or          dword ptr [ebp-0C14h],1  
0011845A  mov         dword ptr [ebp-0C34h],eax  
00118460  jmp         WinMain+18Ch (11847Ch)  
00118462  push        0  
00118464  lea         ecx,[ebp-0C28h]  
0011846A  call        DataDecoder<char *>::DataDecoder<char *> (117770h)

如您所见,类构造函数在两种情况下都被调用,“SOMEDATA”和 NULL 也是如此!

这是正确的行为吗?我该如何处理?

更新:我打开了对文件的预处理,这就是我看到的:

LPSTR lpTemp = lpAdditionalData ? DataDecoder<char*>("SOMEDATA") : 0;

所以,这不是预处理器的问题。

【问题讨论】:

    标签: c++ class visual-c++ macros ternary-operator


    【解决方案1】:

    与任何表达式一样,涉及条件运算符的表达式必须具有类型。表达式c ? a : b 不能神奇地具有在运行时根据c 的值而改变的类型——有时是a 的类型,有时是b 的类型。相反,如果ab 属于不同类型,则有复杂的规则可以通过尝试将一个强制转换为另一个类型来确定整个表达式的最终类型。

    在您的情况下,DataDecoder&lt;char*&gt;(x) 不能强制转换为 NULL 的类型,但 NULL 可以通过用户定义的转换 DataDecoder&lt;char*&gt;(NULL) 强制转换为 DataDecoder&lt;char*&gt;。这就是你观察到的。

    【讨论】:

    • 谢谢,是的。我将DataDecoder&lt;char*&gt; 转换为(char*),现在问题解决了。
    猜你喜欢
    • 2012-04-02
    • 1970-01-01
    • 2016-04-10
    • 2015-09-01
    • 2017-11-22
    • 2018-06-23
    • 2023-03-10
    • 2016-03-11
    • 1970-01-01
    相关资源
    最近更新 更多