我有一个班级:
class InputMap
{
public:
template<typename Function>
void setHotkey(sf::Keyboard::Key hotkey, Function onClick)
{
map[hotkey] = onClick;
}
void triggerHotkey(sf::Keyboard::Key hotkey)
{
if(map.find(hotkey) != map.end())
map[hotkey]();
}
protected:
std::map <sf::Keyboard::Key, std::function<void()>> map;
};
并且在调用setHotkey函数时如下:
setHotkey(sf::Keyboard::Left, [=](){TestActor->move(sf::Vector2f(-20, 0));});
setHotkey(sf::Keyboard::Right, [=](){TestActor->move(sf::Vector2f(20, 0));});
我收到这些错误:
../Tyrant/include/Framework/InputMap.hpp|14|error: ‘void TGE::InputMap::setHotkey(sf::Keyboard::Key, Function) [with Function = TGE::State::setHotkey(sf::Keyboard::Key, Function) [with Function = TestState::enter()::__lambda2]::__lambda1]’, declared using local type ‘TGE::State::setHotkey(sf::Keyboard::Key, Function) [with Function = TestState::enter()::__lambda2]::__lambda1’, is used but never defined [-fpermissive]|
../Tyrant/include/Framework/InputMap.hpp|14|error: ‘void TGE::InputMap::setHotkey(sf::Keyboard::Key, Function) [with Function = TGE::State::setHotkey(sf::Keyboard::Key, Function) [with Function = TestState::enter()::__lambda3]::__lambda1]’, declared using local type ‘TGE::State::setHotkey(sf::Keyboard::Key, Function) [with Function = TestState::enter()::__lambda3]::__lambda1’, is used but never defined [-fpermissive]|
||=== Build finished: 2 errors, 1 warnings ===|
现在我猜我可以用-fpermissive编译,但我想避免这样做。
编辑:
显然错误是因为InputMap的.cpp文件包含
template<typename Function>
void setHotkey(sf::Keyboard::Key hotkey, Function onClick)
{
map[hotkey] = onClick;
}
,标题是
template<typename Function>
void setHotkey(sf::Keyboard::Key hotkey, Function onClick);
所以我猜它不喜欢声明和实现在不同的文件中,可能是因为模板?有没有正确的方法来做到这一点,或者我应该只在标题中使用它?
答案 0 :(得分:0)
这是因为执行模板实例化的方式。
定义必须在实例化的翻译单元中完全可见。
将实现放在.cpp中使得该定义仅在那个翻译单元中可见。
粗略地说,每个翻译单元有一个.cpp文件(虽然我看到了一些奇怪的,生病的东西......)。
因此,为了解决您的问题,您可以将实现移动到声明它的标头中。