如下代码:
#include <iostream>
#include <atlstr.h>
int main()
{
CComBSTR bstr(L"test");
std::wcout << bstr << std::endl;
std::wcout << static_cast<BSTR>(bstr) << std::endl;
}
版画
033FA16C
测试
我试图用调试器调查每种情况下发生的转换,但是两次都进入了operator BSTR
。那么,为什么第一行打印地址而第二行打印文本呢?
我们可以从中完全删除ATL,因为这实际上是如何wcout
工作的问题。
考虑下面的最小示例:
#include <iostream>
struct Foo
{
operator const wchar_t*() const { return L"what"; };
};
int main()
{
Foo f;
std::wcout << f << std::endl;
std::wcout << (const wchar_t*)f << std::endl;
}
// Output:
// 0x400934
// what
在您的示例中,从到的隐式转换被触发,但不是由实例化的模板触发的(因为该转换是“用户定义的”,并且模板参数匹配不考虑用户定义的转换)。那么唯一可行的候选者为非模板,到您的转换通过。CComBSTR
BSTR
operator<<(const wchar_t*)
operator<<(const void*)
BSTR
实际上,在标准(LWG 2342)中提出了一个解决方案,该提案的文本对此进行了更详细的说明。
综上所述:
对于宽流参数类型
wchar_t const*
,wchar_t
仅作为模板参数支持。模板参数匹配不考虑用户定义的转换。因此不适当重载operator<<
时是所必需的参数,它是与用于行为不一致的隐式转换被选择char const*
和char
,是意想不到的,并且是无用的结果。
剩下的唯一可行的重载就是一个,const void*
并且,因为每个指针都可以隐式转换为const void*
,所以这就是您要获得的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句