申し訳ありませんが、これが少し複雑になった場合。エラーの原因を絞り込むために、オブジェクトを取得して不要なものをすべて削除しました。これが私のエラーの原因です:
d3d11module.h
#ifndef STUFF_H
#define STUFF_H
#include <map>
#include <string>
#include <memory>
class D3D11
{
public:
class Shader;
template<class T>
class ShaderRegister;
typedef std::map<std::string, std::shared_ptr<Shader>(*)()> SHADER_CREATE_MAP;
private:
static SHADER_CREATE_MAP createMap;
};
class D3D11::Shader
{
};
template<class T>
std::shared_ptr<D3D11::Shader> createShader() {return std::shared_ptr<D3D11::Shader>(new T);}
template<class T>
class D3D11::ShaderRegister
{
public:
ShaderRegister(std::string const & s)
{
D3D11::createMap.insert(std::pair<std::string,std::shared_ptr<Shader>(*)()>(s, &createShader<T>));
}
};
#endif
このすべての本当に簡単な説明。いくつかのクラスを含むd3d11というクラスがあります。まず、クラスが派生して実装できるシェーダークラスですが、内容が問題とは関係がないため、ここでは空白のままにします。次に、関数ポインタに対応する文字列インデックスのマップがあります。
ShaderRegisterオブジェクトは、派生シェーダークラス内の静的プライベートメンバーになります。次に、そのすぐ外側でコンストラクターが呼び出され、指定されたインデックスとcreateShader()へのポインターがそのインデックスに格納されます。これを行うことにより、インデックスを呼び出すと、このテンプレート化された関数が呼び出され、その派生シェーダーのインスタンスが返されます。
ただし、シェーダーオブジェクトを派生させ、ShaderRegisterのインスタンスを作成し、そのコンストラクターを呼び出そうとすると、リンクエラーが発生します。見てください:
#ifndef DIFFUSE_SHADER
#define DIFFUSE_SHADER
#include "d3d11module.h"
class DiffuseShader : public D3D11::Shader
{
static D3D11::ShaderRegister<DiffuseShader> reg;
};
D3D11::ShaderRegister<DiffuseShader> DiffuseShader::reg("DiffuseShader");
#endif
これを行うと、非常に苦痛に見えるリンクエラーが発生します。
main.obj : error LNK2001: unresolved external symbol "private: static class std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::tr1::shared_ptr<class D3D11::Shader> (__cdecl*)(void),struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class std::tr1::shared_ptr<class D3D11::Shader> (__cdecl*)(void)> > > D3D11::createMap" (?createMap@D3D11@@0V?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6A?AV?$shared_ptr@VShader@D3D11@@@tr1@2@XZU?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6A?AV?$shared_ptr@VShader@D3D11@@@tr1@2@XZ@std@@@2@@std@@A)
それでも、私が言おうとしているのは、d3d11クラスの静的マップオブジェクトは、ある時点で使用されたときに未定義であるということです。しかし、静的オブジェクトはプログラムの最初に作成されたと思いました。どうしたの?