template<typename T>
class ClassVariantVisitor : public boost::static_visitor<T>
{
public:
T operator()(int& i) const {
try
{
return boost::lexical_cast<T>(i);
}
catch (boost::bad_lexical_cast& e)
{
throw e.what();
}
}
T operator()(double& d) const {
try
{
return boost::lexical_cast<T>(d);
}
catch (boost::bad_lexical_cast& e)
{
throw e.what();
}
}
// ...
};
ご覧のとおり、operator()
の実装コードはまったく同じです。コードを簡素化できる現実的な方法はありますか?boost :: static_vistorの派生クラスを簡略化する方法
は、コンパイラ(G ++)はerrorsのトンを生成しますコメントに基づいて更新
// //
template<typename T>
class ClassVariantVisitor : public boost::static_visitor<T>
{
public:
T operator()(T& i) const {
try
{
return boost::lexical_cast<T>(i);
}
catch (boost::bad_lexical_cast& e)
{
throw e.what();
}
}
};
ありがとうございます。 を見てわかるように、コンパイラは、コンパイル時間中にエラーまたは警告を生成しません:
/////はiammilindするiammilind
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <boost/variant.hpp>
#include <boost/lexical_cast.hpp>
using namespace std;
typedef boost::variant<int, double, string> VarIntDoubleString;
// T is the result_type
template<typename T>
class ClassVariantVisitor : public boost::static_visitor<T>
{
public:
template<typename U>
T operator()(U& i) const {
try
{
return boost::lexical_cast<T>(i);
}
catch (boost::bad_lexical_cast& e)
{
throw e.what();
}
}
};
int main(void)
{
map<string, VarIntDoubleString> mapValuesThree;
// store & retrieve char
mapValuesThree["char_fieldI"] = VarIntDoubleString('c');
char fieldI = boost::apply_visitor(ClassVariantVisitor<char>(), mapValuesThree["char_fieldI"]);
cout << "fieldI: " << fieldI << endl;
}
~/Documents/C++/boost $ g++ -o p192f4 p192f4.cpp -Wall
~/Documents/C++/boost $ ./p192f4
terminate called after throwing an instance of 'char const*'
aborted
~/Documents/C++/boost $ g++ --version
g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
からのコメントに基づいて2を更新しました。
//は3私はブースト:: MPLについての知識がないと、それを動作させることができないコンスタンチンOznobihin
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <boost/variant.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/utility/enable_if.hpp>
using namespace std;
template<typename T>
class ClassVariantVisitor : public boost::static_visitor<T>
{
public:
typedef boost::mpl::vector<int, double, string> VarIntDoubleString;
template <class U>
typename boost::enable_if<
typename boost::mpl::contains<VarIntDoubleString, U>::type, T>::type operator()(U &v) const
{
try
{
return boost::lexical_cast<T>(v);
}
catch (boost::bad_lexical_cast& e)
{
throw e.what();
}
}
};
int main(void)
{
map<string, ClassVariantVisitor::VarIntDoubleString> mapValuesThree;
// store & retrieve double
mapValuesThree["double_fieldJ"] = ClassVariantVisitor<double>::VarIntDoubleString(2.3456);
double fieldJ = boost::apply_visitor(ClassVariantVisitor<double>(), mapValuesThree["double_fieldJ"]);
cout << "fieldJ: " << fieldJ << endl;
}
からのコメントに基づいて更新します。 errors を参照してください。あなたのアイデアを使用して機能させるためにコードを修正する方法を教えてください。 はあなた
テンプレートを使用できないのはなぜですか? –
私は更新された投稿のあなたのコメントに対処しました。 – q0987
@ q0987:あなたのテンプレートは間違っています。あなたは 'T'を再利用できません.iammilindのように' operator() 'テンプレートに新しいパラメータを指定する必要があります。私は 'char const *'を投げるという考えも批判します。 'boost :: bad_lexical_cast'がここに伝播するようにする方がはるかにクリーンです。 @MatthieuM。 –