是否可以使用宏魔术或TMP在编译时将长度插入字符串?
例如:
const wchar_t* myString = L"Hello";
我希望缓冲区实际上包含“[length] [string constant]”。
我正在使用缺少constexpr的MSVC 2010。我认为必须有一些技巧可以让这项工作成为可能:
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++ template string concatenation
但不是两个字符串常量的连续,而是从第二个长度生成的常量:)
答案 0 :(得分:1)
您无法创建编译时BSTR
。 BSTR
被定义为由SysAllocString
和家人分配。如果它不是BSTR
,而是冒名顶替者。
但是,如果在编译时知道BSTR
的内容,您可以拥有一个全局BSTR
变量,并且只分配一次,避免您关注的数千个分配。
即,将变量声明为BSTR
,但使用SysAllocString
将其初始化为字符串。
E.g:
BSTR bsHello = SysAllocString(L"Hello");
答案 1 :(得分:1)
对于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)))