0

私はクラスを持っています:

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);

おそらくテンプレートのせいで、宣言と実装が異なるファイルにあるのは好きではないと思いますか?これを行う適切な方法はありますか、それともヘッダーにのみ含めることになっていますか?

4

1 に答える 1

0

これは、テンプレートのインスタンス化が実行される方法が原因です。

定義は、それがインスタンス化される翻訳単位内で完全に可視でなければなりません。

実装を .cpp に配置すると、定義はその翻訳単位内でのみ表示されます。

大雑把に言えば、翻訳単位ごとに 1 つの .cpp ファイルです (ただし、奇妙なもの、病気のものをいくつか見てきました...)。

したがって、問題を解決するには、実装を宣言されているヘッダーに移動できます。

于 2013-11-10T08:59:38.933 に答える