В C++ вы можете инициализировать объект std::string
из char *
и const char *
, и это подразумевает, что строка будет заканчиваться сначала NUL
символом, найденным после указателя.Почему бы не разрешить инициализацию std :: string из массива символов?
В строковых литералах C++, однако, массивы и конструктор шаблонов могут использоваться для получения правильного размера, даже если строковый литерал содержит встроенные NUL
s. Смотри, например, следующую реализацию игрушек:
#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;
}
Есть ли какие-либо конкретные технические причины, по которым этот подход не был рассмотрен для стандарта и вместо строкового литерала со встроенными NUL
с заканчивается усекается, когда используется для инициализации std::string
объект?
Для начала, после 'char a [100] =" foo "; std :: string s = a; ',' s.length() 'вероятно, не должно быть 100. –
" строковый литерал со встроенными NUL заканчивается тем, что усекается при инициализации объекта std :: string "- только если это произойдет. –
Вероятно, потому что наличие строк со встроенными нулевыми символами является исключительным случаем, с которым можно было бы обращаться другими способами. –