作为一个学习练习,我一直在研究自动类型转换在C++中的工作原理.我知道通常应该避免自动类型转换,但我想通过了解它的工作原理来增加我对C++的了解.
我已经创建了一个StdStringConverter可以自动转换为a的类std::string,但编译器(Debian上的g ++ 4.3.4)似乎不会在将对象与real进行比较时进行转换std::string(请忽略缺少传递引用和不必要的临时对象创建):
#include <string>
class StdStringConverter
{
public:
explicit StdStringConverter(std::string name) : m_name(name) {}
operator const std::string () const { return m_name; }
private:
std::string m_name;
};
int main()
{
StdStringConverter converter(std::string("Me"));
const std::string name = "Me";
// Next line causes compiler error:
// no match for 'operator==' in 'converter == name'
return (converter == name) ? 0 : 1;
}
Run Code Online (Sandbox Code Playgroud)
在另一方面,如果我稍微改变到一个CStringConverter类,自动转换不会发生,但比较char可能的指针是不是我想要的结果:
#include <string> …Run Code Online (Sandbox Code Playgroud) 我想测量以下两件事:
str ="1,2,3,4,1,2,"
然后str.Count(',')返回我6在上面的字符串的情况下,str.FindAllOccurancesOF("1,2,")
返回我2在c ++中有没有用于计算的内置函数,或者我需要为此编写自定义代码?
这个以前回答问题,解释了为什么我已张贴下面的代码不起作用.我有一个后续问题:是否存在概念上等效的解决方法,即实现编译时字符串连接,但是以C++ 11实际支持的方式实现?使用std :: string是完全不必要的.
constexpr std::string foo() { return std::string("foo"); }
constexpr std::string bar() { return std::string("bar"); }
constexpr std::string foobar() { return foo() + bar(); }
Run Code Online (Sandbox Code Playgroud) 当我看到在gcc中实现std :: string的方式时,我注意到sizeof(std :: string)正好等于指针的大小(x32 build中为4个字节,x64为8个字节).因为字符串应该保存一个指向字符串缓冲区的指针,并且它的长度是最小值,这使我认为GCC中的std :: string对象实际上是指向保存此数据的某个内部结构的指针.
因此,当创建新字符串时,应该发生一个动态内存分配(即使字符串为空).
除了性能开销之外,这还会导致内存开销(当我们分配非常小的内存块时会发生这种情况).
所以我只看到这种设计的缺点.我错过了什么?有什么好处,首先是这样实施的原因是什么?
众所周知,从C++ 11开始,std::basic_strings被认为具有空字符终止的内部存储缓冲区.
除其他之外,这种变化的主要原因是之前的定义std::basic_string只允许对字符串进行非常有限的并发访问,因此对多线程应用程序的性能有限.(有关更改原因的更多信息,请std::basic_string参阅提案N2534).
但是,阅读标准我找不到明确声明std::basic_string必须具有空字符终止内部存储缓冲区的引用.
我发现的唯一隐含引用是§21.4.7.1/ 1和3 basic_string访问器[string.accessors]:
const charT* c_str() const noexcept;
const charT* data() const noexcept;
1返回:一个指针p,p + i == &operator[](i)用于每个iin[0,size()].3要求:程序不得更改存储在字符数组中的任何值.
我认为,由于提高效率,并且由于§21.4.7.1/3要求的程序,不得改变返回的缓冲区,在大多数实施者std::basic_string::c_str()和 std::basic_string::data()正在返回空字符结束内部缓冲区.
但是,该标准并未声明必须返回的缓冲区,std::basic_string::c_str()并且std::basic_string::data()必须是该std::basic_string字符串的内部存储缓冲区,而不是某些空字符终止副本.
std::basic_string内部存储缓冲区必须为空字符终止?std::basic_string不带有空字符终止的内部存储缓冲区,从而实现自C++ 11以来的广泛传播概念字符串是null终止是错误的? 我有一个核心转储std::string,我想在gdb中检查.打印它会将其内容作为以null结尾的字符串,但如何访问其他std::string属性,如大小和容量?试图s.size()直接访问会导致错误,"如果没有调试过程,就无法做到这一点."
我有一个C++ std::string str,我已经设置为一些字符串,现在想要重置,以便它可以再次使用.呼叫str.clear()vs 之间有区别str = ""吗?
编辑.澄清一下:我通过在其中添加一个char数组缓冲区来重用str:str.append(buf)
据我所知,std::string_view是一个非所属参照字符串之间的主要差异std::string_view,并std::string有
现在,为什么std :: string_view不适用于其他类型?或者为什么这个实现仅适用于std::string?
例如:如果我们有类似的<T>generic_view地方T可以是任何类型,包括自定义类型.
有了这个,可以使用而不是使用const T& as函数参数<T>generic_view.而且其他优点std::string_view也很有用,如分配,复制等.
在Visual Studio 2013中,如果我写,编译器将报告错误:
std::string test = 3;
Run Code Online (Sandbox Code Playgroud)
显示:
错误C2440:'initializing':无法从'int'转换为'std :: basic_string,std :: allocator>'.
但是,如果我将其更改为:
std::string test = "";
test = 3;
Run Code Online (Sandbox Code Playgroud)
它只是编译!当然最终会有悲剧性的错误.
为什么会这样?
从cppref的描述capacity()以及reserve()是否计入终止空字符尚不清楚。