我在Visual Studio 2008中有一个C ++ / Win32 / MFC项目,编译时我收到一条奇怪的错误信息。
我创建了一个小项目来演示问题,主要代码是
#ifndef _MyObject_h
#define _MyObject_h
class MyObject
{
public:
MyObject()
{
}
};
#endif // _MyObject_h
// --- END MyObject.h
// --- BEGIN ObjectData.h
#ifndef _ObjectData_h
#define _ObjectData_h
template <typename DataPolicy>
class ObjectData
{
public:
DataPolicy *data;
ObjectData() :
data(NULL)
{
}
ObjectData(const ObjectData<DataPolicy> ©) :
data(copy.data)
{
}
ObjectData<DataPolicy> & operator=(const ObjectData<DataPolicy> ©)
{
this->data = copy.data;
return *this;
}
};
#endif // _ObjectData_h
// --- END ObjectData.h
// --- BEGIN Tool.h
#ifndef _Tool_h
#define _Tool_h
#include "ObjectData.h"
template <typename ObjectPolicy>
class Tool
{
private:
ObjectData<typename ObjectPolicy> _object;
public:
Tool(ObjectData<typename ObjectPolicy> obj);
};
#endif // _Tool_h
// --- END Tool.h
// --- BEGIN Tool.cpp
#include "stdafx.h"
#include "Tool.h"
template <typename ObjectPolicy>
Tool<ObjectPolicy>::Tool(ObjectData<typename ObjectPolicy> obj) :
_object(obj)
{
}
// --- END Tool.cpp
// --- BEGIN Engine.h
#ifndef _Engine_h
#define _Engine_h
#include "Tool.h"
#include "MyObject.h"
class Engine
{
private:
MyObject *_obj;
public:
Engine();
~Engine();
void DoSomething();
};
#endif // _Engine_h
// --- END Engine.h
// --- BEGIN Engine.cpp
#include "stdafx.h"
#include "Engine.h"
Engine::Engine()
{
this->_obj = new MyObject();
}
Engine::~Engine()
{
delete this->_obj;
}
void Engine::DoSomething()
{
ObjectData<MyObject> objData;
objData.data = this->_obj;
// NEXT LINE IS WHERE THE ERROR OCCURS
Tool< ObjectData<MyObject> > *tool = new Tool< ObjectData<MyObject> >(objData);
}
// --- END Engine.cpp
错误:
Engine.cpp
c:\ projects \ myproject \ myproject \ engine.cpp(18):错误C2664:
'工具::工具(ObjectData)':无法将参数1从'ObjectData'转换为'ObjectData'
与
[
ObjectPolicy =目标数据,
DataPolicy =目标数据
]
和
[
DataPolicy =为MyObject
]
和
[
DataPolicy =目标数据
]
没有可用于执行此转换的用户定义转换运算符,或者无法调用运算符 1&gt;构建日志保存在“file:// c:\ Projects \ MyProject \ MyProject \ Debug \ BuildLog.htm”中
MyProject - 1个错误,0个警告
感谢您的帮助。
答案 0 :(得分:4)
您的代码存在一些问题。首先,您以错误的方式使用typename
关键字。 typename
只能在使用限定类型名称时使用(并且在类型名称依赖时需要),这不是您的情况:
template <typename ObjectPolicy>
class Tool
{
private:
ObjectData<typename ObjectPolicy> _object; // "typename" is not needed!
public:
Tool(ObjectData<typename ObjectPolicy> obj); // "typename" is not needed!
};
然而,您抱怨的问题在于Tool
类模板的实例化:
Tool< ObjectData<MyObject> > *tool = new Tool< ObjectData<MyObject> >(objData);
您的Tool<>
模板包含ObjectData<ObjectPolicy>
类型的成员变量,其中ObjectPolicy
是类模板参数。但是,在上面的行中,您使用Tool
作为参数实例化ObjectData<MyObject>
。这意味着您的成员变量将具有类型ObjectData<ObjectData<MyObject>>
,这也是构造函数参数的类型。
因此,您尝试调用一个构造函数,该构造函数接受带有不匹配类型ObjectData<ObjectData<MyObject>>
的参数的ObjectData<MyObject>
。因此,你得到的错误。
您应该将实例化更改为:
Tool< MyObject > *tool = new Tool< MyObject >(objData);
另一个问题是,您在单独的Tool
文件中定义了.cpp
的成员函数。您不应该这样做:链接器在处理单独的翻译单元时将无法看到它。
要解决此问题,请将类模板的成员函数的定义放入定义类模板的同一标头中(在您的情况下为Tool.h
)。
答案 1 :(得分:0)
Tool< ObjectData<MyObject> > *tool = new Tool< ObjectData<MyObject> >(objData);
template <typename ObjectPolicy>
Tool<ObjectPolicy>::Tool(ObjectData<typename ObjectPolicy> obj) :
_object(obj)
{
}
在我看来,您可能不太了解模板的工作原理。 查看以下C++ Templates 您目前拥有的是无效的C ++语法。看看并再试一次。