使用std :: string参数和不可移动/可复制的参数构建std :: map

时间:2015-03-10 16:37:37

标签: c++ c++11 stl

我正在尝试构建一个简单的日志系统,但我遇到了我的概念问题:

class logger_instance
{
    std::string log_file;
    std::string log_type;
    std::ofstream log;

public:
    logger_instance(std::string log_type) : log_type(log_type), log_file("logs\\" + log_type + ".log"), log(log_file)
    {
        operator << ("logger_instance(" + log_type + ") init.\n");
    }

    std::string get_log_type() const
    {
        return log_type;
    }

    std::string get_log_file() const
    {
        return log_file;
    }


    logger_instance& operator << (std::string message)
    {
        time_t current_time;
        time(&current_time);

        log << ctime(&current_time);
        log << " : ";
        log << message;
        log << "\n";
    }
};

class logger_manager
{
    std::map < std::string, logger_instance > loggers;

public:
    void add_logger(std::string logger)
    {
        auto it = loggers.find(logger);

        if (it == loggers.end())
        {
            loggers.emplace(logger, logger);
        }
    }

    logger_instance& operator[](std::string logger)
    {
        return loggers[logger];
    }
};

编译器:Visual Studio 2013 Update 4

我遇到的问题是,emplace函数似乎并不理解我希望logger_instance对象在map容器中现场构建。鉴于我并不比编译器更聪明,问题在于我的概念,但我无法找到解决方案。

1 个答案:

答案 0 :(得分:0)

地图上的进驻是一件相当奇怪的事情。我会推荐Scott Meyers的最新书或查看talk。这是关于cwuks(斯科特的术语)。

但要解决你的问题。使用堆。 通过将logger_instance更改为manager中的unique_ptr。 E.g:

class logger_manager
{
    std::map < std::string, unique_ptr<logger_instance> > loggers;
public:
    void add_logger(std::string logger)
    {
        auto it = loggers.find(logger);
        if (it == loggers.end())
        {
            loggers.emplace(logger, make_unique<logger_instance>(logger));
        }
    }

    logger_instance& operator[](std::string logger)
    {
        return *loggers[logger];
    }
};