Вопрос

Я внедряю общего считывателя. Идея заключается в том, что у меня есть приложение, которое настройки могут быть логическими, целыми числами и строками. Затем у меня есть класс конфигурации, в котором реализованы Getters для таких настроек, класс конфигурации берет клиента в конструктор, чтобы он знал, что он будет читать настройки для этого самого клиента.

У меня проблемы с тем, что я работаю, я думаю, что я неправильно использую Boost :: Function сбивает с толку это с простым указателем функции.

На картах я хотел бы иметь ссылки, пока 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;
}

Обновление он работал, используя ссылки на функции в картах, а не Boost :: 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