所以,我有一个类根据附加到字符串中每个字符的元数据进行字符串操作。在内部,我用std::vector<CharacterType>
代表这个,其中CharacterType
包含所讨论的角色等。这个内部表示对我很有用,但是在操作结束时,类用户对字符串本身感兴趣。
为了做到这一点,我决定扩展std::vector<CharacterType>::iterator
以包含一个返回字符而不是operator*()
的{{1}}方法。这是代码,它适用于Windows 7上的Visual Studio 2008但是它是惯用的C ++吗?自90年代以来,我没有写过很多C ++,所以我很欣赏一些关于风格的反馈,或者我是否正在做一些危险和/或邪恶的事情。 (在下面的代码中,我创建了一个名为CharacterType
的简化CharacterType
结构 - 实际上结构要大得多。)
mytype
假设这是一个好的样式,使用C ++类型感知方法重载是否合适在#include <iostream>
#include <vector>
#include <string>
struct mytype {
char c;
};
class myit : public std::vector<mytype>::iterator {
public:
inline myit(std::vector<mytype>::iterator const &c)
: std::vector<mytype>::iterator(c) {}
char operator*() {
const mytype &p =
std::vector<mytype>::iterator::operator*();
return p.c;
}
// Added these in a later edit, after thinking about a comment below
typedef char value_type;
typedef char *pointer;
typedef char &reference;
private:
};
int
main()
{
mytype test[] = { {'a'}, {'b'}, {'c'}, {'d'} };
std::vector<mytype> vec(&test[0], &test[4]);
myit i(vec.begin()), e(vec.end());
std::string str(i, e);
std::cout << str << std::endl;
return 0;
}
中有几个operator*()
方法,以便我可以使用相同的迭代器类来获取另一个成员不同的类型?或者使用模板会更好吗?例如,一个元数据是角色的语言,我希望能够以完全相同的方式提取myit
。想法?
此外,由于返回这些数据的方法不会影响对象的内部表示,为了保证const的正确性,我希望能够定义访问器std::vector<LanguageType>
。这可能意味着我需要修改上面的内容才能使用const
代替,但我还没有达到目的。
提前感谢你的风格批评!
答案 0 :(得分:0)
首先,我希望能够在这么长的休息之后写出如此优秀的C ++,如果它应该发生在我身上的话!
说,从CharacterType
到char
排除简单转化运算符的原因是什么?类似于:CharacterType::operator char();
当然,我们都知道运算符重载的问题(但在两种情况下不会改变)......
关于你问的其他事情,你不能基于返回类型重载,所以你不可能为不同的返回类型设置不同的operator(),如果这就是你的意思。
但正如你所提到的,你可以使用模板。
答案 1 :(得分:0)
你不应该派生std :: vector(也不是其他STL容器),因为它的析构函数不是虚拟的,你可以遇到没有调用vector的析构函数并且你得到内存泄漏的情况。
答案 2 :(得分:0)
我不相信你可以在同一个班级中“多次operator*()
重载”;大概你想要基于返回类型消除歧义,但C ++不会这样做。
另外,直接从不相关的迭代器类型派生可能不是一个好主意。为了作为STL迭代器正确运行,迭代器类需要定义许多typedef等。如果你直接继承它们,那么你的任何一个都没有意义。有关更多信息,请参阅例如这篇文章在Custom Containers & Iterators for STL-Friendly Code。
答案 3 :(得分:0)
您通过从operator*()
返回CharacterType以外的类型来破坏多个迭代器契约。老实说 - 如果你迫切希望它们可以转换,只需给出operator char()
字符。
答案 4 :(得分:0)
一些不同的人建议我研究转换运算符,我必须承认我完全忘了。基于转换运算符的解决方案相当简洁:
#include <iostream>
#include <vector>
#include <string>
struct mytype {
char c;
inline operator char () { return c; }
};
int
main()
{
mytype test[] = { {'a'}, {'b'}, {'c'}, {'d'} };
std::vector<mytype> vec(&test[0], &test[4]);
std::string str(vec.begin(), vec.end());
std::cout << str << std::endl;
return 0;
}
...并且它不会让我担心违反STL迭代器合同等不祥的声音。另外,似乎(虽然我还没有尝试过)如果我希望能够轻松复制除字符串之外的其他内容(原始问题中的std::vector<LanguageType>
想法),我可以通过添加来轻松扩展一个不同的强制转换操作符,而迭代器派生技术需要更多样板,因为C ++中没有返回类型多态,正如几个人指出的那样。
非常感谢您的回复,一旦我得到代表,我会全力支持您,以防您想知道我为什么还没有。