是否有用constexpr string\u视图替换全局const char[]的gotchas? 我们团队正在使用一个10年以上的C++代码库,最近切换到C++ 17编译器。因此,我们正在寻找使代码现代化的方法。在YouTube上的一次会议演讲中,我听到了用constepr string\u view替换constchar*全局字符串的建议

是否有用constexpr string\u视图替换全局const char[]的gotchas? 我们团队正在使用一个10年以上的C++代码库,最近切换到C++ 17编译器。因此,我们正在寻找使代码现代化的方法。在YouTube上的一次会议演讲中,我听到了用constepr string\u view替换constchar*全局字符串的建议,c++,c++17,constexpr,string-view,C++,C++17,Constexpr,String View,由于我们的代码中有很多这样的const char*全局字符串常量,我想问一下,我们是否有需要注意的问题或潜在问题?这些问题可能值得注意: std::string\u视图不需要以null结尾。因此,如果用string\u视图替换一些const char*,并通过std::string\u视图::substr用string\u视图替换先前的null终止的char*子字符串的构造,您不能将底层指针传递给期望以null结尾的字符串的API。示例(没有UB,但也很容易构造): 虽然可以从const ch

由于我们的代码中有很多这样的
const char*
全局字符串常量,我想问一下,我们是否有需要注意的问题或潜在问题?

这些问题可能值得注意:

  • std::string\u视图
    不需要以
    null
    结尾。因此,如果用
    string\u视图
    替换一些
    const char*
    ,并通过
    std::string\u视图::substr
    string\u视图
    替换先前的
    null
    终止的
    char*
    子字符串的构造,您不能将底层指针传递给期望以
    null
    结尾的字符串的API。示例(没有UB,但也很容易构造):

  • 虽然可以从
    const char*
    隐式构造
    std::string
    ,但不能使用
    std::string\u视图
    。其想法是,深度复制不应在封面下进行,而应在明确要求时进行。例如:

    std::map<std::string, int> m;
    constexpr std::string_view sv = "somekey";
    constexpr const char *old = "somekey";
    
    m[old] = 42; // works as expected
    m[sv] = 42; // fails to compile
    m[std::string(sv)] = 42; // be explicit, this is ok
    
    std::map m;
    constexpr std::string_view sv=“somekey”;
    constexpr const char*old=“somekey”;
    m[旧]=42;//工作如期进行
    m[sv]=42;//未能编译
    m[std::string(sv)]=42;//明确点,这没关系
    
    根据项目中全局
    const char*
    实例的现有用法,此行为可能需要在不同的位置进行手动干预


  • 这种非零终止肯定是一种骗局。现在我需要检查我们的SVs。我想你应该做
    std::string(sv).c_str()
    而不是传递给API?@darune这是一个选项,但是应该检查API的生命周期假设,对吗?!如果您使用
    someLegacyFct(std::string(sv).c_str())
    并且该后端以某种方式存储指针…这是正确的-仅在使用寿命假设的情况下,第二个问题“幸运地”对我们来说不会是什么大问题。我们公司的框架有自己的字符串类(我知道…),带有显式的
    constchar*
    构造函数。因此,在我们的例子中,从
    string\u视图
    显式构造
    std::string
    std::map<std::string, int> m;
    constexpr std::string_view sv = "somekey";
    constexpr const char *old = "somekey";
    
    m[old] = 42; // works as expected
    m[sv] = 42; // fails to compile
    m[std::string(sv)] = 42; // be explicit, this is ok