C++ 为什么对数组的引用没有std::string构造函数?
字符串文字是数组对象:C++ 为什么对数组的引用没有std::string构造函数?,c++,C++,字符串文字是数组对象: typeid(“hello”).name()//字符[6] 这似乎很方便,因为字符串文本(=数组)的大小在编译时是已知的。那么为什么没有引用数组的std::string构造函数呢 //这太好了 模板 std::string(常量字符和数组)[N]); 相反,有些构造函数采用const char*s、const char*s、size\t n或两个inputierators(例如const char*begin、const char*end)。所有这些都有缺点;数组隐式
typeid(“hello”).name()//字符[6]
这似乎很方便,因为字符串文本(=数组)的大小在编译时是已知的。那么为什么没有引用数组的std::string
构造函数呢
//这太好了
模板
std::string(常量字符和数组)[N]);
相反,有些构造函数采用const char*s
、const char*s、size\t n
或两个inputierator
s(例如const char*begin、const char*end
)。所有这些都有缺点;数组隐式转换为指针,大小信息丢失,因此使用各种方法将其取回。工作,但越来越疯狂的例子:
//std::string(const char*s)版本:
std::string s1(“hello”);//在内部调用std::strlen
//标准::字符串(常量字符*s,大小\u t n)版本:
std::string s2(“hello”,5);//程序员在精神上做std::strlen
std::string s3(“hello”,sizeof(“hello”);//必须重复字符串文字
//避免重复字符串文字的宏帮助器(丑陋且危险)
#定义STRLIT(x)std::string(x,sizeof(x));//我想可能是一个函数
std::string s4=STRLIT(“hello”);//没有多少改进(宏是邪恶的)
//标准::字符串(输入计算器开始,输入计算器结束)版本:
char tmp[]=“你好”//复制数组
std::字符串s5(&tmp[0],&tmp[sizeof(tmp)]);//所以你可以引用它两次
//或者信任编译器为两个文本返回相同的地址
std::string s6(&“hello”[0],&“hello”[sizeof(“hello”)]);//完全疯了
这样的模板化构造函数将针对N
的每个值分别实例化。这可能会导致不必要的代码膨胀
膨胀是可以避免的,但让我们将这一想法与不断引用的答案结合起来:
“为什么不存在此功能?”的答案通常是“默认情况下,功能不存在。必须有人来实现它们。”
对于
N
的每个值,将分别实例化这样一个模板化构造函数。这可能会导致不必要的代码膨胀
膨胀是可以避免的,但让我们将这一想法与不断引用的答案结合起来:
“为什么不存在此功能?”的答案通常是“默认情况下,功能不存在。必须有人来实现它们。”
因为有一个使用迭代器的通用构造函数:
std::string s7(std::begin(container), std::end(container));
注意:假设std::begin/std::end使用c++11,但您可以很容易地快速编写类似的内容。因为有一个使用迭代器的通用构造函数:
std::string s7(std::begin(container), std::end(container));
注意:假设std::begin/std::end使用c++11,但是您可以很容易地快速编写类似的内容。考虑是否应该有一个构造函数接受字符常量(&)[N](对于一些静态确定的
N
)时,关键问题是结果std::string
的内容应该是什么。对某些人来说,这可能是显而易见的,但我不认为是这样。考虑这个<代码> STD::String(“ABC \0DEF”)< /代码>:
std::cout << "string='" << "abc\0def" << "'\n";
std::cout在考虑是否应该有一个构造函数采用char const(&)[N]
(对于一些静态确定的N
)时,关键问题是结果std::string
的内容应该是什么。对某些人来说,这可能是显而易见的,但我不认为是这样。考虑这个<代码> STD::String(“ABC \0DEF”)< /代码>:
它可以是一个包含8个元素的字符串,包括两个空字节
它可以是一个包含7个元素的字符串,不包括第二个空字节
它可以是一个包含3个元素的字符串,不包括从第一个空字节开始的所有内容
如果你使用
std::cout << "string='" << "abc\0def" << "'\n";
std::您是否可以编写自己的make_string
函数来执行此操作。仅供参考,sizeof
捕获空字节并返回6。STRLIT
可以是内联函数,而不是宏tmeplate std::string strlit(const char(&str)[len]){return std::string(str,len);}
(这也是Pubby建议的)字符串文本是数组对象,不是类型。一个好的编译器会为文本字符串提供一个固定时间版本的strlen。您可以编写自己的make_string
函数来实现这一点。仅供参考,sizeof
捕获空字节并返回6。STRLIT
可以是一个内联函数,而不是宏tmeplate std::string strlit(const char(&str)[len]){return std::string(str,len);}
(这也是Pubby所建议的)字符串文字是数组对象,而不是类型。一个好的编译器会为文字字符串提供一个固定时间版本的strlen
。无意义,零构造所有成员,然后调用assign(ptr,size)
,内联后,每个N
都不会膨胀,要扩展@Mooing Duck所说的内容,使用C++11,它所要做的就是委托给字符串(ptr,size)
构造函数。代表团几乎肯定会加入进来。没有膨胀。好吧,我建议的是稍微不太可能内联,但碰巧也在C++03中工作,零构造所有成员,然后调用assign(ptr,size)
,内联后,每个N
都没有膨胀,要扩展@Mooing Duck所说的内容,使用C++11,它所要做的就是委托给字符串(ptr,size)
constructor。委托几乎肯定是内联的。没有膨胀。好吧,我建议的是内联的可能性稍微小一些