为什么不允许字符数组初始化std :: string?

650*_*502 2 c++ arrays string string-literals

在C ++中,您可以std::string从a char *和a 初始化一个对象const char *,这隐式地假定字符串将在NUL指针之后的第一个字符处结束。

在C ++中,字符串文字是数组,并且即使字符串文字包含Embedded,也可以使用模板构造函数来获取正确的大小NUL。例如,请参见以下玩具实现:

#include <stdio.h>
#include <string.h>
#include <vector>
#include <string>

struct String {
    std::vector<char> data;
    int size() const { return data.size(); }

    template<typename T> String(const T s);

    // Hack: the array will also possibly contain an ending NUL
    // we don't want...
    template<int N> String(const char (&s)[N])
        : data(s, s+N-(N>0 && s[N-1]=='\0')) {}

    // The non-const array removed as probably a lot of code
    // builds strings into char arrays and the convert them
    // implicitly to string objects.
    //template<int N> String(char (&s)[N]) : data(s, s+N) {}
};

// (one tricky part is that you cannot just declare a constructor
// accepting a `const char *` because that would win over the template
// constructor... here I made that constructor a template too but I'm
// no template programming guru and may be there are better ways).
template<> String::String(const char *s) : data(s, s+strlen(s)) {}

int main(int argc, const char *argv[]) {
    String s1 = "Hello\0world\n";
    printf("Length s1 -> %i\n", s1.size());
    const char *s2 = "Hello\0world\n";
    printf("Length s2 -> %i\n", String(s2).size());
    std::string s3 = "Hello\0world\n";
    printf("std::string size = %i\n", int(s3.size()));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

是否有任何特定的技术原因不考虑将这种方法用于标准,而是将带有嵌入式NULs 的字符串文字用于初始化std::string对象时最终被截断了?

小智 6

C ++ 14引入了字符串文字的后缀以使它们成为std::string对象,因此主要用例不再相关。

#include <iostream>
#include <string>
using namespace std;
using namespace std::literals;

int main() {
    string foo = "Hello\0world\n";
    string bar = "Hello\0world\n"s;
    cout << foo.size() << " " << bar.size() << endl; // 5 12
    cout << foo << endl; // Hello
    cout << bar << endl; // Helloworld
    return 0;
}
Run Code Online (Sandbox Code Playgroud)