c++ - 三元运算符将类扩展宏应用于两个操作数

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

我使用 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 ? a : b不能神奇地拥有一个在运行时根据 c 的值而改变的类型- a 的类型有时,b 的类型其他时间。相反,如果 ab有不同的类型,有复杂的规则来确定整个表达式的最终类型,通过尝试将一个类型强制转换为另一个类型。

在你的例子中,DataDecoder<char*>(x)不能强制转换为 NULL 的类型,但是 NULL可以强制为 DataDecoder<char*> , 通过用户定义的转换 DataDecoder<char*>(NULL) .这就是您所观察到的。

关于c++ - 三元运算符将类扩展宏应用于两个操作数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36097655/

相关文章:

c++ - Arduino 上的 C/C++ 字符串 .replace() 函数不起作用

python - 如何在 Python 中正确排序对象列表

java - 使用什么IDE?

c++ - 与 Boost 错误链接

c++ - 如何制作一个 "operator"变量? (C++)

c++ - 私有(private)变量的范围

c++ - 以列表作为值初始化 map

c++ - 作为类成员的 2D vector 指针

Java - 从 Jar 文件创建类

java - 如何从 JSNI 调用 Dll 方法以在 GWT Web 应用程序中使用?