문제

일반 설정 리더를 구현하고 있습니다. 아이디어는 설정이 부울, 정수 및 문자열 일 수있는 응용 프로그램이 있다는 것입니다. 그런 다음 해당 설정의 getters가 구현되는 구성 클래스가 있으며 구성 클래스는 생성자의 고객을 가져 가므로 해당 고객의 설정을 읽을 것임을 알고 있습니다.

나는 그 일을하는 데 어려움을 겪고 있습니다. 나는 Boost를 잘못 사용하고 있다고 생각합니다 :: 기능을 일반 기능 포인터와 혼동합니다.

지도에서 나는 참조를 원한다. boost::function 내가 할당 한 이후로 구성된 시간에만 묶어야한다. Config 주어진 고객의 인스턴스.

문제는 typedefs없이 기능 포인터를 사용할 수 없으며 이것이 더 현명한 솔루션 인 템플릿 작업을 복잡하게한다는 것입니다.

#include "Config.h"

class ConfigReader
{

    ConfigReader();

    template<class R>
    R readConfig(std::string customer, std::string settingName);

private:

        typedef bool (Config::* BoolConfigFunctor) () const;
    std::map<std::string, BoolConfigFunctor> boolConfigMap;

        typedef int(Config::* IntConfigFunctor) () const;
    std::map<std::string, IntConfigFunctor> integerConfigMap;

        typedef std::string (Config::* StrConfigFunctor) () const;
    std::map<std::string, StrConfigFunctor> stringConfigMap;

    template<class R>
    std::map<std::string, R (Config::* ) () >  getConfigMap();
}

ConfigReader()
{
    // INIT all settings you want to be readable in the functor maps
    boolConfigMap["USE_NEW_VERSION"]    = &Config::useNewVersion;
    boolConfigMap["MAINTENANCE_MODE"]   = &Config::isMaintenance;
    integerConfigMap["TIMEOUT"]         = &Config::getTimeout;
    stringConfigMap["USERNAME"]         = &Config::getUserName;
            ...
}

template<class R>
R readConfig(std::string customer, std::string settingName)
{
    R returnValue;

    typedef typename std::map<AMD_STD::string,  R (Config::* ) () > ConfigMap_t;
    typedef typename ConfigMap_t::const_iterator ConfigMapIter_t;

    ConfigMap_t configMap = getConfigMap<R>();
    ConfigMapIter_t configIter = configMap.find(settingName);

    if (configIter != configMap.end())
    {
        Config config(customer); // Real instance of Config against which we want to call the function

        boost::function<R ()> configFunction;
        configFunction =
                boost::bind(
                        configIter->second,
                        config);

        returnValue= configFunction();
    }

    return returnValue;
}

template<>
std::map<std::string, bool (Config::* ) ()>  ConfigReader::getConfigMap()
{
    return boolConfigMap;
}

template<>
std::map<std::string, int (Config::* ) ()>  ConfigReader::getConfigMap()
{
    return integerConfigMap;
}

template<>
std::map<std::string, string (Config::* ) ()>  ConfigReader::getConfigMap()
{
    return stringConfigMap;
}

업데이트는 부스트 :: function 대신 맵에서 함수 참조를 사용하여 작동했습니다.

도움이 되었습니까?

해결책

멤버 함수가없는 한 멤버 기능 포인터를 일반 함수 포인터로 사용할 수 없습니다. static. 대신 사용해야합니다 부스트 바인드 특정 개체 인스턴스 :

boolConfigMap["USE_NEW_VERSION"] = boost::bind(&Config::useNewVersion, someInstanceOfConfig);

(정적이 아닌) 멤버 함수 포인터가 정상 함수 포인터 (또는 정적 멤버 함수 포인터)와 동일하지 않은 이유는 멤버 함수가 숨겨진 "Zeroeth"인수를 가지고 있기 때문입니다. this 멤버 함수 내부의 포인터.

또한, 당신의 선언 boost::function 물체는 예를 들어야합니다

boost::function<bool()>

이는 모든 유형의 기능을 반환합니다 bool 그리고 논쟁을 취하지 않습니다.


컴파일러가 충분히 새로운 경우 사용하도록 변경하고 싶을 수도 있습니다. std::function 그리고 std::bind.


멤버 함수 포인터로 표시하기 위해 편집 한 후 : 기능 포인터를 올바르게 호출해야합니다.

(config.*configIter->second)();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top