You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用std::wstring_view作为std::map的std::wstring键及实现语法糖?

问题

我尝试构建一个以std::wstring为键的std::map结构,希望通过宏和std::wstring_view简化常量键的声明与定义。当前map定义如下:

class Parameter
{
public:
    typedef std::wstring Key; 

    std::variant<void*, int, bool, float, std::wstring> value_;

    ...
}

typedef std::map<Parameter::Key, Parameter> Parameters;

使用字符串字面量访问map无问题:

myParameters[L"SomeKey"] = L"SomeValue";

但使用std::wstring_view定义常量键时出现错误:

static constexpr std::wstring_view SomeKeyDefined = L"SomeKey";
myParameters[SomeKeyDefined] = L"SomeValue";

错误信息:

C2679: binary '[': no operator found which takes a right-hand operand of type 'const std::wstring_view' (or there is no acceptable conversion)

我原以为std::wstring_view是const std::wstring的包装,想咨询是否可以用std::wstring_view作为该map的键?最终我希望通过宏实现语法糖来定义常量键,例如:

#define PARAMETER_KEY_STRING(x) L # x
#define PARAMETER_KEY(name) static constexpr std::wstring_view name = PARAMETER_KEY_STRING(name);

从而可以通过PARAMETER_KEY(SomeKey)来定义常量键。若此方式不可行,有没有其他实现std::wstring常量键语法糖的方法?

解决方案

关于std::wstring_view作为map键的疑问

std::wstring_view并非const std::wstring的包装,它只是对宽字符序列的非拥有式视图,两者属于不同类型。std::map<std::wstring, ...>的operator[]仅接受能隐式转换为std::wstring的类型,而std::wstring_view到std::wstring不存在隐式转换(需要显式构造),因此直接用wstring_view访问会触发编译错误。

要使用wstring_view操作现有map,有两种可行方案:

  • 显式转换为std::wstring:访问时手动构造wstring对象,示例如下:
    myParameters[std::wstring(SomeKeyDefined)] = L"SomeValue";
    
    缺点是每次访问都会生成临时wstring,存在额外的内存分配与拷贝开销。
  • 修改map键类型为std::wstring_view:如果键对应的字符串(比如常量字面量)生命周期长于map,这种方式安全且高效,因为wstring_view不管理内存,避免了wstring的构造开销:
    typedef std::map<std::wstring_view, Parameter> Parameters;
    
    此时用wstring_view常量键直接访问map即可正常编译运行。

实现std::wstring常量键的语法糖

若坚持使用std::wstring作为map键,可调整宏定义直接生成const std::wstring类型的常量:

#define PARAMETER_KEY(name) static const std::wstring name = L#name;

使用PARAMETER_KEY(SomeKey)定义后,SomeKey就是const std::wstring类型,直接用myParameters[SomeKey]访问不会有类型问题。

针对C++17及以上版本,建议用inline变量避免多定义问题:

#define PARAMETER_KEY(name) inline static const std::wstring name = L#name;

内容的提问来源于stack exchange,提问作者lfgtm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 07:53:12