当调用一个期望BSTR的函数时,能够编写类似的东西很好:
iFoo->function( bs"HELLO" );
然而,我唯一知道的解决方法是使用调用SysAllocString
等的包装器,例如:
iFoo->function( WideString(L"HELLO").c_bstr() );
这有点难看。实际上是否存在创建BSTR
字面值的选项?
动机:通过避免分配和释放,更易于阅读的代码和更快的运行时性能。
澄清:我只讨论调用者(即我们)拥有BSTR所有权的情况,例如:调用带有BSTR [in]
参数的函数。当然,向一个函数提供指向BSTR文字的指针是愚蠢的,这个函数将继续尝试释放字符串。
答案 0 :(得分:4)
用户定义的文字将是最佳选择:
"HELLO"_bstr
调用template<char...> BSTR operator "" _bstr ( const char*, std::size_t)
,然后可以调用SysAllocString()
VS14中的新功能。
[编辑]
根据评论,最好返回_bstr_t
或其他获得SysAllocString()
结果所有权的类,并隐式转换为BSTR
。此临时值将在完整表达式结束时销毁,因此 iFoo->function( "HELLO"_bstr );
之后的将返回。
答案 1 :(得分:3)
要跟进@ MSalters的回答,自定义用户定义的文字可能如下所示:
CComBSTR operator "" _bstr (const char* str, std::size_t len)
{
return CComBSTR(len, str);
}
然后您可以执行此操作(因为CComBSTR
已定义BSTR
转化运算符):
iFoo->function( "HELLO"_bstr );
您甚至可以为多个输入字符串文字类型重载运算符:
CComBSTR operator "" _bstr (const wchar_t* str, std::size_t len)
{
return CComBSTR(len, str);
}
CComBSTR operator "" _bstr (const char16_t* str, std::size_t len)
{
return CComBSTR(len, (wchar_t*)str);
}
iFoo->function( L"HELLO"_bstr ); // calls wchar_t* version with UTF-16 encoded data
iFoo->function( u"HELLO"_bstr ); // calls char16_t* version with UTF-16 encoded data
iFoo->function( u8"HELLO"_bstr ); // calls char* version with UTF-8 encoded data...
请注意最后一种情况。由于运算符不知道它是传递ANSI还是UTF-8数据,并且CComBSTR
在传递char*
数据时假设ANSI,您应该使用不同的文字后缀来区分,以便您可以转换UTF -8正确,例如:
CComBSTR operator "" _utf8bstr (const char* str, std::size_t len)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> conv;
std::wstring wstr = conv.from_bytes(std::string(str, len));
return CComBSTR(wstr.length(), wstr.c_str());
}
iFoo->function( u8"HELLO"_utf8bstr );