Возможно ли использовать макро-магию или TMP для вставки длины в строку во время компиляции?
Например:
const wchar_t* myString = L"Hello";
Я хотел бы, чтобы буфер фактически содержал «[length] [string constant]».
Я использую MSVC 2010, в котором отсутствует constexpr. Я подумал, что должен быть какой-то трюк, чтобы сделать эту работу максимально возможной:
const wchar_t* myString = L"\x005Hello";
Моя попытка пока:
template<int Size>
wchar_t* toBstr(const wchar_t* str)
{
#pragma pack(push)
#pragma pack(1)
struct BStr
{
int len;
wchar_t data[Size];
};
#pragma pack(pop)
static BStr ret;
ret.len = Size;
// don't want to have to copy here, how else could this work??
//ret.data = str;
return ret.data;
}
const wchar_t* m = toBstr<_countof(L"Hello")>(L"Hello");
Этот вопрос кажется связанным:
Конкатенация строк шаблона C ++
Но не конкат для двух строковых констант, а константа, сгенерированная из длины 2-й 🙂
Вы не можете создать время компиляции BSTR
, BSTR
определены для распределения SysAllocString
и семья. Если это не так, это не BSTR
, но самозванец.
Однако, если содержание BSTR
известен во время компиляции, вы можете иметь глобальный BSTR
переменная, и распределите ее только один раз, избегая тысяч выделений, которые вас беспокоят.
Т.е. иметь переменную, объявленную как BSTR
, но инициализировать его в строку, используя SysAllocString
,
Например.:
BSTR bsHello = SysAllocString(L"Hello");
За BSTR
которые передаются в функции только для чтения, Я использую этот простой макрос:
#define DECLARE_BSTR(Variable, String)\
struct \
{ \
uint32_t uLength; \
OLECHAR szData[sizeof(String)]; \
} \
Variable = {sizeof(String) - sizeof(OLECHAR), String};
Пример:
ITaskFolder *pTaskFolder;
DECLARE_BSTR(static bstrTaskFolderName, L"\\");
if (SUCCEEDED(pTaskService->GetFolder(bstrTaskFolderName.szData, &pTaskFolder)))
Вариант, который можно использовать вместо BSTR
то есть без .szData
:
#define DECLARE_BSTR(Variable, String) \
struct \
{ \
uint32_t uLength; \
OLECHAR szData[sizeof(String)]; \
operator const OLECHAR *() const {return szData;}\
operator OLECHAR *() {return szData;}\
} \
Variable = {sizeof(String) - sizeof(OLECHAR), String};
Пример:
ITaskFolder *pTaskFolder;
DECLARE_BSTR(static bstrTaskFolderName, L"\\");
if (SUCCEEDED(pTaskService->GetFolder(bstrTaskFolderName, &pTaskFolder)))