gpt4 book ai didi

c++ - 在 C++ 模板中使用抽象类型时出错

转载 作者:搜寻专家 更新时间:2023-10-31 02:21:13 24 4
gpt4 key购买 nike

我在用 C++ 实现侵入式容器时遇到了一些奇怪的问题。给定以下简化代码:

struct IFace {
virtual int foo() const = 0;
};

struct Impl : public IFace {
int foo() const { return 111; }
};

template <typename T> struct IntrusiveHook {
T item;
IntrusiveHook<T>* next;
};

template <typename T> struct IntrusiveList {
IntrusiveList() : head(0), tail(0) {}

template <typename U>
void add(IntrusiveHook<U>& addItem) {
if (0 == head) {
head = reinterpret_cast<IntrusiveHook<T>*>(&addItem);
tail = head;
}
else {
tail->next = reinterpret_cast<IntrusiveHook<T>*>(&addItem);
tail = tail->next;
}
}
IntrusiveHook<T>* head;
IntrusiveHook<T>* tail;
};

void testList() {
IntrusiveHook<Impl> impl;
IntrusiveList<IFace> list;

list.add(impl);
// list.head->item.foo();
}

我收到以下错误消息 - 对于“添加”调用(如上注释行 list.head->item.foo() 时):

error C2259: 'IFace' : cannot instantiate abstract class
due to following members:
'int IFace::foo(void) const' : is abstract
testwas.cpp(7) : see declaration of 'IFace::foo'
testwas.cpp(25) : see reference to class template instantiation 'IntrusiveHook<T>' being compiled
with
[
T=IFace
]
testwas.cpp(41) : see reference to function template instantiation 'void IntrusiveList<T>::add<Impl>(IntrusiveHook<Impl> &)' being compiled
with
[
T=IFace
]

list.head->item.foo() 行评论时我得到了一个不同的编译错误,前一个被遗漏了(这是一种奇怪的行为,在 VC++ 和 gcc 编译器上都会发生)

有问题的电话似乎是tail->next = ...或者特别是运算符(operator) ->关于这里使用的抽象类型。

所以:如何解决这个问题?

  • foo 添加默认实现在IFace - 这不是我想要的,但它解决了问题
  • 有点古怪的解决方案:重写为 tail->next作为

    reinterpret_cast<IntrusiveHook<U>*>(tail)->next = &addItem;

    tail = reinterpret_cast<IntrusiveHook<T>*>(reinterpret_cast<IntrusiveHook<U>*>(tail)->next); - 但它似乎不适用于 VC++(2010),但适用于 gcc

  • ...或执行其他一些丑陋的类型转换

但是为什么这首先是一个问题?通常用运算符“->”访问指针类型应该不是问题。

如有任何帮助,我们将不胜感激。谢谢!


编辑:

为了方便起见,我希望 IntrusiveHook 已经包含该项目作为实例。这也是侵入式的技巧 - 当我做对时 - 只需将指针功能添加到项目而不更改项目本身。 "new"不是一个选项,因为代码应该在没有 new 的嵌入式环境中运行。 .

当然我也想使用带有抽象项的列表,因为使用类不知道实现类。

最佳答案

据我所知,问题是转换为 IntrusiveHook<T>*IntrusiveList::add .您正在转换 addItemIntrusiveHook<IFace> . IntrusiveHook<IFace>有成员(member)item类型 IFace .但是IFace是抽象的,因此您不能声明具有该类型的变量——您必须使用指针或引用。

所以你必须

  • 更改IntrusiveHook::item来自类型 TT* ,
  • 添加构造函数IntrusiveHook(T* item) : item(item) {} ,
  • 更改impl的声明在testList()IntrusiveHook<Impl> impl(new Impl)
  • 最后更改list.head->item.foo()list.head->item->foo() .

(参见 this code on cpp.sh 。)

你也可以使用 IntrusiveList<IFace*>IntrusiveList<Impl>而不是 IntrusiveList<IFace>如果你不想改变 IntrusiveHook .

关于c++ - 在 C++ 模板中使用抽象类型时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31673884/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com