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)': パラメータ 1

[
ObjectPolicy=ObjectData,
DataPolicy=ObjectData
]
および
[
DataPolicy=MyObject
]
および
[
DataPolicy=ObjectData
]
この変換を実行できるユーザー定義変換演算子がないか、演算子を呼び出すことができません
1>ビルド ログが「file://c: \Projects\MyProject\MyProject\Debug\BuildLog.htm"
MyProject - 1 エラー、0 警告

助けてくれてありがとう。

4

2 に答える 2

5

コードにはいくつかの問題があります。まず、typenameキーワードの使い方が間違っています。修飾typenameされた型名が使用されている場合にのみ使用できます(型名がdependentの場合に必要です)。これはあなたの場合ではありません:

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<>には type のメンバー変数が含まれています。ObjectData<ObjectPolicy>ここObjectPolicyで、 はクラス テンプレート パラメーターです。ただし、上記の行では、パラメーターとしてインスタンス化ToolObjectData<MyObject>ています。これは、メンバー変数が type を持つことを意味し、これObjectData<ObjectData<MyObject>>はコンストラクターのパラメーターの型にもなります。

ObjectData<ObjectData<MyObject>>このため、一致しない type の引数を持つを受け入れるコンストラクターを呼び出そうとしていますObjectData<MyObject>。したがって、エラーが発生します。

インスタンス化を次のように変更する必要があります。

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

もう 1 つの問題は、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 に答える