无法将参数 1 从 'Component<W> *' 转换为 'Component<W> *'
Cannot convert parameter 1 from 'Component<W> *' to 'Component<W> *'
我创建了一个小样本来演示这个问题。我真不明白这里出了什么问题。使用Visual Studio 2010。
这些类(非常松散地)以MFC
为模型,因为这正是我需要使用它的原因。基本上,我想创建一个面板类,它可以包含其他面板或控件,所以我添加了一个跟踪id和父级的组件类,以及作为其组件容器的面板类。
现在我不明白的是,为什么我会得到这个编译器错误,为什么我只在使用控件而不使用子面板时才会得到它。
#include <iostream>
#include <algorithm>
#include <vector>
class CWnd
{
public:
CWnd(CWnd *pParent = NULL, int nId = -1)
{
mId = nId;
mParent = pParent;
mClassname = NULL;
}
void setId(int nId) { mId = nId; }
int getId(void) const { return mId; }
void setParent(CWnd *pParent) { mParent = pParent; }
CWnd *getParent(void) const { return mParent; }
bool create(const char *pClassname, int nId, CWnd *pParent)
{
mId = nId;
mParent = pParent;
mClassname = pClassname;
return true;
}
private:
int mId;
CWnd *mParent;
const char *mClassname;
};
class Ctrl : public CWnd
{
public:
Ctrl(CWnd *pParent, int nId = -1)
: CWnd(pParent, nId)
{
}
};
class Dialog : public CWnd
{
public:
Dialog(CWnd *pParent, int nId = -1)
: CWnd(pParent, nId)
{
}
bool create(int nId, CWnd *pParent)
{
CWnd::create("dialog", nId, pParent);
return true;
}
};
class View : public CWnd
{
public:
View(CWnd *pParent = NULL)
: CWnd(pParent)
{
}
};
template <typename W>
class Component : public W
{
public:
Component(CWnd *pParent = NULL)
: W(pParent)
{
mId = -1;
mParent = pParent;
}
virtual bool create(CWnd *pParent = NULL)
{
if(pParent)
mParent = pParent;
W::setParent(mParent);
W::setId(mId);
return true;
}
private:
int mId;
CWnd *mParent;
};
class Panel : public Component<Dialog>
{
public:
Panel(CWnd *pParent = NULL)
: Component(pParent)
{
}
virtual bool create(CWnd *pParent = NULL)
{
if(pParent != NULL)
setParent(pParent);
Dialog::create(getId(), pParent);
for(Components::iterator it = mComponents.begin(); it != mComponents.end(); ++it)
{
if(!(*it)->create(this))
return false;
}
return true;
}
void addComponent(Component *pComponent)
{
if(std::find(mComponents.begin(), mComponents.end(), pComponent) == mComponents.end())
mComponents.push_back(pComponent);
}
void removeComponent(Component *pComponent)
{
Components::iterator pos = std::find(mComponents.begin(), mComponents.end(), pComponent);
if(pos != mComponents.end())
mComponents.erase(pos);
}
protected:
typedef std::vector<Component *> Components;
private:
Components mComponents;
};
int main()
{
View v;
Panel d;
Panel p;
Component<Ctrl> listbox;
Component<Ctrl> tab;
// these are generating the error
d.addComponent(&listbox);
d.addComponent(&tab);
// only this one works.
d.addComponent(&p);
std::cout << "nDone! Press any key..." << std::endl;
std::cin.ignore();
return 0;
}
我得到的错误信息是:
'Panel::addComponent' : cannot convert parameter 1 from 'Component<W> *' to 'Component<W> *'
没有类型Component
,所以没有类型Component*
。然而,在Panel
类的上下文中,由于它是从Component<Dialog>
派生的,因此实际上注入了名称Component
,并引用了Component<Dialog>
。因此addComponent
的正确签名是:
void addComponent(Component<Dialog> *pComponent)
但是Component<Ctrl>
不是从Component<Dialog>
派生的,所以Component<Ctrl>*
不能传递给这个函数。
您可能想要做的是从第二个基类派生Component
(它不是从任何东西派生的)。
class Component_base
{
// component common functionality
};
template<typename W>
class Component : public W, public Component_base
{
...
};
然后您的Panel
类可以存储:
std::vector<Component_base*> Components;
有一种叫做注入类名的东西。对于类模板,这意味着在类模板的范围内,类模板名称指的是特定的实例化,而不是模板本身:
template <class T>
class C {
C(C<T> const& ) = default; // one way to write the copy constructor
C(C const& ) = default; // exactly equivalent to the above
};
继承的类也继承所有注入的类名。所以当你写:
class Panel : public Component<Dialog>
我们有多个不同的注入名称:Panel
、Component
、Dialog
和CWnd
。这是第二个重要的:在Panel
的范围内,Component
指的是特定的类Component<Dialog>
,而不是类模板Component
。因此:
void addComponent(Component *pComponent)
是的缩写(完全等同于)
void addComponent(Component<Dialog> *pComponent)
Component<Dialog>
和Component<Ctrl>
之间没有类关系,因此出现错误。
根据您的评论,您实际上希望这是一个函数模板。所以你必须明确地把它变成一个:
template <class W>
void addComponent(Component<W> *pComponent) { ... }
但这不会起作用,因为你持有vector<Component<Dialog>*>
。您还需要将其更改为vector<CWnd*>
。
您的问题是没有从Component<Ctrl>*
到Component<Dialog>*
的转换。CCD_ 28工作是因为CCD_ 29和CCD_。您需要为Component<Ctrl>*
和Component<Dialog>*
创建公共基类来进行这样的转换,或者在这两种类型之间创建转换构造函数。
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中