字符串文字是数组对象:
typeid("hello").name() // char [6]
这看起来很方便,因为字符串文字(=数组)的大小在编译时是已知的。那么为什么std::string
没有构造函数引用数组?
// this would be great
template <int N>
std::string(const char (& array)[N]);
相反,有些构造函数需要const char * s
,const char * s, size_t n
或两个InputIterator
s(例如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
答案 0 :(得分:2)
对于N
的每个值,将单独实例化这样的模板化构造函数。这可能会导致不必要的代码膨胀。
臃肿是可以避免的,但让我们将这个想法与来自永远引用的Raymond Chen的答案结合起来:
答案“为什么不存在此功能?”通常是“默认情况下功能不存在。有人必须实现它们。”
答案 1 :(得分:1)
在考虑构造函数是否应该使用char const (&)[N]
(对于某些静态确定的N
)时,关键问题是结果std::string
的内容应该是什么。对某些人来说可能是显而易见的,但我认为不是。考虑一下这个std::string("abc\0def")
:
如果您使用
std::cout << "string='" << "abc\0def" << "'\n";
你得到第三个选择。看来,这是唯一理智的选择......
答案 2 :(得分:0)
因为有一个使用迭代器的泛型构造函数:
std::string s7(std::begin(container), std::end(container));
注意:对于std :: begin / std :: end假设c ++ 11,但你可以很容易地快速编写类似的内容。