1

字符串文字是数组对象:

typeid("hello").name()   // char [6]

这似乎很方便,因为字符串文字(=array)的大小在编译时是已知的。那么为什么没有构造函数来std::string引用数组呢?

// this would be great
template <int N>
std::string(const char (& array)[N]);

const char * s相反,有些构造函数采用const char * s, size_t n或两个InputIterators(例如。const char * begin, const char * end)。所有这些都有缺点;数组被隐式转换为指针并且大小信息丢失,因此使用各种方法将其取回。工作,但越来越疯狂的例子:

// std::string(const char * s) version:
std::string s1("hello");                      // calls std::strlen(s) internally

// std::string(const char * s, size_t n) version:
std::string s2("hello", 5);                   // programmer does std::strlen(s) mentally
std::string s3("hello", sizeof("hello"));     // have to repeat string literal

// macro helper to avoid repeating string literal (ugly and dangerous)
#define STRLIT(x) std::string(x, sizeof(x));  // could be a function I guess
std::string s4 = STRLIT("hello");             // not much improvement (and macros are evil)

// std::string(InputIterator begin, InputIterator end) version:
char tmp[] = "hello";                         // copy array
std::string s5(&tmp[0], &tmp[sizeof(tmp)]);   // so you can reference it twice

// or trust the compiler to return the same address for both literals
std::string s6(&"hello"[0], &"hello"[sizeof("hello")]);   // totally crazy
4

3 回答 3

2

这样的模板化构造函数将为N. 这可能会导致不必要的代码膨胀。

膨胀是可以避免的,但让我们将这个想法与常被引用的Raymond Chen的回答结合起来:

“为什么不存在此功能?”的答案 通常是“默认情况下功能不存在。必须有人来实现它们。”

于 2012-11-27T23:48:19.260 回答
1

因为有一个使用迭代器的通用构造函数:

std::string s7(std::begin(container), std::end(container));

注意:假设 std::begin/std::end 为 c++11,但您可以快速轻松地编写类似的东西。

于 2012-11-28T00:03:36.590 回答
1

考虑是否应该有一个构造函数采用 a char const (&)[N](对于某些静态确定N的)时,关键问题是结果的内容std::string应该是什么。对于某些人来说,它应该是什么可能是显而易见的,但我不认为它是。考虑一下std::string("abc\0def")

  1. 它可以是一个包含 8 个元素的字符串,包括两个空字节。
  2. 它可以是一个包含 7 个元素的字符串,不包括第二个空字节。
  3. 它可以是一个包含 3 个元素的字符串,不包括从第一个空字节开始的所有内容。

如果你使用

std::cout << "string='" << "abc\0def" << "'\n";

你得到第三个选项。看来,这是唯一明智的选择...

于 2012-11-28T00:04:00.583 回答