Is there a way to write a BSTR literal?

When calling a function expecting BSTR, it would be nice to write something like:

iFoo->function( bs"HELLO" );

      

However, the only workaround I know of is to use a shell that calls SysAllocString

etc., for example:

iFoo->function( WideString(L"HELLO").c_bstr() );

      

which is kind of ugly. Is there such a way to create a literal BSTR

?

Motivation: Easier to read code and better runtime performance by avoiding allocation and deallocation.

Clarification: I'm only talking about situations where the caller (that is, we) owns the BSTR, for example: calling a function that takes a parameter BSTR [in]

. Of course, it would be foolish to supply a BSTR literal pointer to a function that will continue to try to free the string.

+3


source to share


2 answers


To follow up on @ MSalters answer, a custom user-defined literal might look something like this:

CComBSTR operator "" _bstr (const char* str, std::size_t len)
{
    return CComBSTR(len, str);
}

      

Then you can do this (since it CComBSTR

has a conversion operator BSTR

):

iFoo->function( "HELLO"_bstr );

      

You can even overload the operator for multiple types of input literals:



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...

      

Pay attention to the last case. Since the operator will not know if the data is being transmitted ANSI or UTF-8, but CComBSTR

accepts ANSI when transmitting data char*

, you must use a different literal suffix for differentiation so that you can convert UTF-8 correctly, for example:

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 );

      

+2


source


Custom literals would be as follows:

"HELLO"_bstr

calls template<char...> BSTR operator "" _bstr ( const char*, std::size_t)

, which can then callSysAllocString()

New in VS14.



[edit]

Based on the comments, it is better to go back _bstr_t

or another class that takes responsibility for the result SysAllocString()

and implicitly converts to BSTR

. This temporary value will be destroyed at the end of the complete expression, and therefore upon return iFoo->function( "HELLO"_bstr );

.

+4


source







All Articles