San*_*lín 1 c++ inheritance stdstring
我知道 std::string不是为继承而设计的,但是,我想知道为什么这个类定义不能编译:
\nusing std::string;\nclass ExtendedString: public string\n{\npublic:\n using string::string;\n ExtendedString left(size_type n) const {\n return substr(0, n>size()?size():n);\n }\n};\nRun Code Online (Sandbox Code Playgroud)\n我收到此错误:
\n../../src/capel-tool.cpp:21:17: error: could not convert \xe2\x80\x98std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::substr(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type, std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type) const [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int](0, ((n > ((const ExtendedString*)this)->ExtendedString::<anonymous>.std::__cxx11::basic_string<char>::size()) ? ((const ExtendedString*)this)->ExtendedString::<anonymous>.std::__cxx11::basic_string<char>::size() : n))\xe2\x80\x99 from \xe2\x80\x98std::__cxx11::basic_string<char>\xe2\x80\x99 to \xe2\x80\x98ExtendedString\xe2\x80\x99\nRun Code Online (Sandbox Code Playgroud)\n我预计left函数将使用 std::string 中的任何默认构造函数。
即使我添加一个像这样的显式构造函数:
\nusing std::string;\nclass ExtendedString: public string\n{\npublic:\n using string::string;\n ExtendedString left(size_type n) const {\n return substr(0, n>size()?size():n);\n }\n\n explicit ExtendedString(const std::string &s);\n};\nRun Code Online (Sandbox Code Playgroud)\n我仍然遇到同样的错误。
\n仅当我添加普通构造函数时:
\nusing std::string;\nclass ExtendedString: public string\n{\npublic:\n using string::string;\n ExtendedString(const std::string &s);\n ExtendedString left(size_type n) const {\n return substr(0, n>size()?size():n);\n }\n};\nRun Code Online (Sandbox Code Playgroud)\n代码编译正常。
\n现在想象一下我想对一个专为继承而设计的类做同样的事情。难道我不能以一种类可以互换使用的方式创建这种包装器,而不需要创建构造函数,它将被创建和调用,而不仅仅是“语法糖”
\n编辑1:
\n这个建议的问题确实解释了为什么我的代码不起作用,但它没有像已接受的问题那样提出任何替代方案。
\n您的代码的问题是substr返回 a std::string,而不是ExtendedString. 类型之间不存在隐式转换,因此 return 语句无法编译。在继承层次结构中存在隐式转换,即您可以转换ExtendedString为std::string,但反之则不行。
要仅针对您的left功能解决此问题:
ExtendedString(const std::string&)return ExtendedString(substr(...))然而,一般来说,您想要做的事情在 C++ 中不太可能实现。您继承的每个成员函数std::string都不会返回ExtendedString,因此您的接口是错误的。C++ 无法让您定义扩展方法,而这是您正在模仿的功能。
std::string创建从to 的隐式转换ExtendedString,但这会导致不必要的复制
ExtendedString(const std::string &s);std::string或者更好的是,将其包装为成员
std::string,并让它们ExtendedString在必要时获取/返回std::string left(const std::string& s, std::size_t n) {
return s.substr(0, std::min(s.size(), n));
}
Run Code Online (Sandbox Code Playgroud)
尽管有时打电话str.function()、有时打电话很烦人function(str),但与任何替代方案相比,这种不一致只是一个很小的代价。