2

我在 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> &copy) :
                data(copy.data)
        {
        }

        ObjectData<DataPolicy> & operator=(const ObjectData<DataPolicy> &copy)
        {
                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:
'Tool::Tool(ObjectData)' : 无法
使用
[
ObjectPolicy=ObjectData,将参数 1 从 'ObjectData' 转换为 'ObjectData'
DataPolicy=ObjectData
]
and
[
DataPolicy=MyObject
]
and
[
DataPolicy=ObjectData
]
没有可以执行此转换的用户定义转换运算符,或者无法调用该运算符
1>构建日志保存在“file://c: \Projects\MyProject\MyProject\Debug\BuildLog.htm"
MyProject - 1 个错误,0 个警告

谢谢你的帮助。

4

2 回答 2

5

您的代码存在一些问题。首先,您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但是,在上面的行中,您将withObjectData<MyObject>作为参数进行实例化。这意味着您的成员变量将具有 type ObjectData<ObjectData<MyObject>>,这也将是构造函数参数的类型。

因此,您试图调用一个构造函数,该构造函数接受ObjectData<ObjectData<MyObject>>一个不匹配类型的参数ObjectData<MyObject>。因此,您得到的错误。

您应该将您的实例化更改为:

Tool< MyObject > *tool = new Tool< MyObject >(objData);

另一个问题是您Tool在单独的.cpp文件中定义了 的成员函数。您不应该这样做:链接器在处理单独的翻译单元时将无法看到它。

要解决此问题,请将类模板的成员函数的定义放入定义类模板的同一标头中(Tool.h在您的情况下)。

于 2013-02-05T18:00:31.153 回答
1
Tool< ObjectData<MyObject> > *tool = new Tool< ObjectData<MyObject> >(objData);

template <typename ObjectPolicy>
Tool<ObjectPolicy>::Tool(ObjectData<typename ObjectPolicy> obj) :
        _object(obj)
{
}

在我看来,您可能并不真正了解模板的工作原理。查看以下C++ 模板 您目前拥有的是无效的 C++ 语法。看一看,再试一次。

于 2013-02-05T18:00:20.943 回答