模板化部分应用程序调用问题

时间:2012-11-28 01:16:48

标签: c++ templates boost functor

对于即将到来的1月份课程,我开始开发一个小型DirectX引擎。为了确定性能是否有所提高,我想尝试不使用任何虚拟机(我知道虚拟机并非都不好,但我只是想看看它是否可能没有它们。)

当我开始使用简单的StateManager时,很难避免虚拟,但这是我目前的做法:

#include <boost\function.hpp>
#include <boost\bind.hpp>

template <class Derived>
struct TBaseState {
  bool update(float delta) {
    return static_cast<Derived *>(this)->update(delta);
  };
};

struct CTestState : TBaseState<CTestState> {
  bool update(float delta) {
      return true;
  }
};

class StateManager
{
public:
    template <class StateClass> static void setState(StateClass nextState)
    {
        m_funcptrUpdate = boost::bind(&TBaseState<StateClass>::update,     boost::ref(nextState), _1);
    }
    static bool update(float delta) 
    {
        return m_funcptrUpdate(delta);
    }
protected:
private:
    static boost::function<bool (float)> m_funcptrUpdate;
};

Visual Studio 2010的Intellisense似乎认为一切都很好,但是当我想编译程序并使用一种非常基本的方法测试StateManager时:

CTestState* t = new CTestState(); 
StateManager::setState(*t);
StateManager::update(0.0f);

在链接阶段抛出以下错误:

error LNK2001: unresolved external symbol "private: static class boost::function<bool __cdecl(float)> StateManager::m_funcptrUpdate" (?m_funcptrUpdate@StateManager@@0V?$function@$$A6A_NM@Z@boost@@A)

显然他找不到绑定功能,但我怎样才能解决这个问题呢?如果我直接对某些类使用boost :: bind,我会得到类似的错误。由于我是一名计算机科学专业的学生,​​我也会对一些没有提升的见解或方法感兴趣(例如bind1st,......)。

编辑: 我也在考虑使用C ++ 11 Variadic模板,但其中一个课程要求是坚持VS2012。

1 个答案:

答案 0 :(得分:1)

需要为静态类成员提供存储空间。它们就像extern个变量。在类定义之外的.cpp文件中添加一个定义:

boost::function<bool (float)> StateManager::m_funcptrUpdate;

此外,在此代码中:

template <class StateClass> static void setState(StateClass nextState)
{
    m_funcptrUpdate = boost::bind(&TBaseState<StateClass>::update,
        boost::ref(nextState), _1);
}

您正在维护存储对局部变量nextState的引用。 <{1}}返回后该引用无效。