这是一段代码:
class Base {
public:
long index;
};
class Derived : public Base {
public:
bool value;
};
void call(map<char *, Base *> *base) {
map<char *, Base *>::iterator it = base->begin();
cout << it->second->index << endl;
}
void test(void) {
map<char *, Derived *> *d = new map<char *, Derived *>;
call(d);
}
编译器警告错误:
error C2664: 'call' : cannot convert parameter 1 from 'std::map<_Kty,_Ty> *' to 'std::map<_Kty,_Ty> *'
1> with
1> [
1> _Kty=char *,
1> _Ty=Derived *
1> ]
1> and
1> [
1> _Kty=char *,
1> _Ty=Base *
1> ]
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
我理解为什么会发生这种错误。 我不明白如何使它工作。什么样的演员以及如何使用它?
UPD
我很抱歉不准确,让我解释一下细节。 我有两组由ClassA和ClassB表示的数据。 这两个类都有一个共同的成员 - 例如“索引”。 两组都被包装成一张地图(特别感谢Rob对char *进行了重大修正):
std::map<char, ClassA>
std::map<char, ClassB>
有时我需要遍历两个映射以获得公共成员“index”的值。 我正在努力避免代码重复,并只使用一个函数迭代两个映射。
我以为我可以用一个普通成员提取一个超类,然后用这样的参数创建一个函数:
std::map<char, SuperClassAB>
或
std::map<char, SuperClassAB>::iterator
但看起来这是一个坏主意。
UPD2
一个聪明的家伙给了我解决方案:
template <class T>
void call(map<char, T> *base) {
map<char, T>::iterator it = base->begin();
cout << it->second->index << endl;
}
void test(void) {
map<char, Derived *> d;
call(&d);
}
答案 0 :(得分:1)
如果您的目标是在派生类上以某种方式“操作”,请在基类上创建一个虚方法并覆盖它以获得所需的特定行为:
class Base
{
public:
long index;
virtual void doSomething()
{
// Do something with index
cout << index << endl;
}
};
class Derived : public Base
{
public:
bool value;
virtual void doSomething()
{
// Do something with value
cout << value << endl;
}
};
// NOTE: I removed the pointer and made it a ref.
// NOTE: I made it "const" because you probably don't want to alter the
// map. If you do...
void call(const map<char *, Base *>& base)
{
map<char *, Base *>::const_iterator it = base.begin();
// cout << it->second->index << endl;
it->second->doSomething();
}
void test(void)
{
map<char *, Base *> d;
// Push some members into d...I didn't, but you should
// if you want call(...) to be meaningful.
call(d);
}
这有用吗?
答案 1 :(得分:1)
您无法投射这些类型。 map<char*,Base*>
和map<char*,Derived*>
与string
和float
不同。
最简单的事情是在test()
内填充map<char*,Base*>
,然后用call
调用virtual
。在Base
中提供virtual
方法(可能是纯Derived
),并在transform
中实施这些功能。
您可以尝试从map<char*,Derived*>
map<char*,Base*>
Base*
Derived
,但为了做到这一点,您的仿函数需要:
static_cast
实际指向Base
个对象,并使用virtual
。dynamic_cast
多态(通常通过实现{{1}}析构函数),并使用{{1}} 答案 2 :(得分:1)
您可能需要容器来存储基类指针而不是派生类指针。
E.g。map<char *, Base *> *d;
。
此后,您应该使用所需的任何派生类型的元素填充地图。 E.g。
char keyA = 'A';
char keyB = 'B';
(*d)[&keyA] = new Derived();
(*d)[&keyB] = new AnotherDerived();
这会在你的实例中起作用吗?
顺便说一下,为什么你使用char *
因为关键似乎是一个奇怪的选择。
答案 3 :(得分:1)
似乎没有人建议这样做,但您也可以将call
作为功能模板。
template <class Type>
void call(const std::map<char*,Type*> & base)
{
static_assert(std::is_base_of<Base, Type>::value,
"Function is only callable with maps "
"whose mapped_type is derived from Base");
/* More stuff */
}
这样,该函数可以使用Base
,Derived
以及从Base
派生的任何其他内容来调用。