我使用 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
的类型其他时间。相反,如果 a
和 b
有不同的类型,有复杂的规则来确定整个表达式的最终类型,通过尝试将一个类型强制转换为另一个类型。
在你的例子中,DataDecoder<char*>(x)
不能强制转换为 NULL
的类型,但是 NULL
可以强制为 DataDecoder<char*>
, 通过用户定义的转换 DataDecoder<char*>(NULL)
.这就是您所观察到的。
关于c++ - 三元运算符将类扩展宏应用于两个操作数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36097655/