我一直在使用我寫的類(這裏是一個減少版本的工作),它提供了一個方法來加載和保存字符串的任何變量,並且可以添加到類中,只要該類中包含此對象它被稱爲_settings_loader。每個變量都通過#define ADD_PARAMETER(x)_settings_loader.AddParameter(#x,x);宏。有沒有更好的方法來做這個C++,從任何類型的文件保存和加載變量?
如果有人能夠提出一種更簡單的擴展方法,而不是針對每種類型使用每種個案,我是否會喜歡它?我知道C++是類型定義的,但有我以前做過的事情(我不想在添加每個變量時使用模板)。
頁眉
#pragma once
#include <boost/any.hpp>
#include <map>
#include <string>
#include <iostream>
#include <vector>
#define ADD_PARAMETER(x) _settings_loader.AddParameter(#x, x);
class SettingsLoader
{
public:
SettingsLoader();
template <class T> void AddParameter(std::string name, T & parameter);
void SetParameter(std::string name, std::string value);
std::string GetParameterValue(std::string name);
void PrintOutParameters();
std::vector<std::pair<std::string, std::string> > GetAllParametersAsStrings();
protected:
std::map<std::string, boost::any> _parameters;
bool _debug;
};
template <class T> void SettingsLoader::AddParameter(std::string name, T & parameter)
{
_parameters.insert(std::make_pair(name, boost::any(¶meter)));
if (_debug)
{
std::cout << "Added parameter " << name << std::endl;
}
}
CPP
#include "settingsloader.h"
#include <boost/lexical_cast.hpp>
SettingsLoader::SettingsLoader():
_parameters(),
_debug(false)
{
}
void SettingsLoader::SetParameter(std::string name, std::string value)
{
try
{
std::map<std::string, boost::any>::iterator itterator = _parameters.find(name);
if (itterator != _parameters.end())
{
boost::any boost_any = itterator->second;
if (boost::any_cast<double*>(boost_any))
{
double * value_to_set = boost::any_cast<double*>(boost_any);
*value_to_set = boost::lexical_cast<double>(value);
}
else if (boost::any_cast<int*>(boost_any))
{
int * value_to_set = boost::any_cast<int*>(boost_any);
*value_to_set = boost::lexical_cast<int>(value);
}
else if (boost::any_cast<long*>(boost_any))
{
long * value_to_set = boost::any_cast<long*>(boost_any);
*value_to_set = boost::lexical_cast<long>(value);
}
}
else
{
if (_debug)
{
std::cout << "Parameter " << name << " could not be set" << std::endl;
}
}
}
catch(...)
{
}
}
std::string SettingsLoader::GetParameterValue(std::string name)
{
try
{
std::map<std::string, boost::any>::iterator itterator = _parameters.find(name);
if (itterator != _parameters.end())
{
boost::any boost_any = itterator->second;
if (boost::any_cast<double*>(boost_any))
{
double * value_to_get = boost::any_cast<double*>(boost_any);
return boost::lexical_cast<std::string>(*value_to_get);
}
if (boost::any_cast<int*>(boost_any))
{
int * value_to_get = boost::any_cast<int*>(boost_any);
return boost::lexical_cast<std::string>(*value_to_get);
}
if (boost::any_cast<long*>(boost_any))
{
long * value_to_get = boost::any_cast<long*>(boost_any);
return boost::lexical_cast<std::string>(*value_to_get);
}
}
}
catch(...)
{
}
return "";
}
std::vector<std::pair<std::string, std::string> > SettingsLoader::GetAllParametersAsStrings()
{
std::vector<std::pair<std::string, std::string>> output_vector;
for (auto pair : _parameters)
{
output_vector.push_back(std::make_pair(pair.first, GetParameterValue(pair.first)));
}
return output_vector;
}
void SettingsLoader::PrintOutParameters()
{
std::cout << "+=======================+" << std::endl
<< "|Printing out parameters|" << std::endl
<< "+=======================+" << std::endl;
std::vector<std::pair<std::string, std::string>> names_and_values = GetAllParametersAsStrings();
for (std::pair<std::string, std::string> pair : names_and_values)
{
std::cout << pair.first << " = " << pair.second << std::endl;
}
}
你可能想要看的一件事是Qt實現的「無類型」對象,[QVariant](https://qt.gitorious.org/qt/qt/source/b12a8d47ba8a803cae88718249b8d3f7d4a85948:src/corelib/kernel/qvariant的.cpp)。請注意,他們也必須爲每種類型的案例編寫不同的代碼,就像你正在做的一樣。沒有更好的方式我知道。 – CmdrMoozy