私のプロジェクトでは、boost::any
とboost::variant
を網羅的に使用しています。このために、以前の質問Generic function to convert boost::any to boost::variantでは、boost::any
からboost::variant
までの一般的な変換ルーチンが考案されました。人々を助けてくれてありがとう。ブーストプリプロセッサを使用したBoost Any Boostバリアント
見つかった解決策は問題なく機能しましたが、重大な欠点がありました。完全にテンプレート化されたソリューションによって生成されたコードの膨らみは、禁止されている可能性があり、単純な変換には不要なことがあります。
簡単な(一般的ではない)変換ではテンプレートの特殊化が機能するようになりましたが、面倒でエラーが発生しやすいタイプのコードが見つかりました。特に、この作業を何度も何度もやり直さなければならない場合。
次のコードスニペットは、この問題を示しています。典型的なアプリケーションでは、20種類以上の画像があるかもしれないというイメージ!
#include <boost/preprocessor.hpp>
#include <boost/variant.hpp>
#include <boost/any.hpp>
#include <boost/optional.hpp>
#include <iostream>
template<typename VARIANT>
boost::optional<VARIANT> anyToVariant(const boost::any& any) {
boost::optional<VARIANT> ret;
// General implementation omitted.
// The implementation is lengthy and produces an enormous code bloat. In some cases it is the best solution.
return ret;
}
// Specialized Template reduces code bloat. But is error-prone to type write for every new variant type.
template<>
boost::optional <boost::variant<int, double, std::string>> anyToVariant(const boost::any& any) {
boost::optional<boost::variant<int, double, std::string>> ret;
if (any.type() == typeid(int)) {
ret = boost::any_cast<int>(any);
}
if (any.type() == typeid(double)) {
ret = boost::any_cast<double>(any);
}
if (any.type() == typeid(std::string)) {
ret = boost::any_cast<std::string>(any);
}
return ret;
}
// Should be implemented with boost preprocessor
#define BOOST_ANY_TO_VARIANT(TypeList)
// Better would be a macro like this
BOOST_ANY_TO_VARIANT(int, double, std::string); // Create the above template specialization
int main() {
boost::variant<int, double, std::string> v;
boost::any x = 4;
v=*anyToVariant<boost::variant<int, double, std::string>>(x);
}
よりよい解決策はもちろん、マクロだろうが、残念ながら私はboost-preprocessor
でこのマクロを実装することができませんでした。私はまだスキルが不足していますが、それができると確信しています。
経験がある方はboost-preprocessor
で問題を解決できますか?
私が想像できる最良の解決策は、以下のようなマクロのようになります。
#define BOOST_ANY_TO_VARIANT(VariantType) \
// Magic?
typedef boost::variant<int, std::string, double> MyVariant;
BOOST_ANY_TO_VARIANT(MyVariant)
しかし、私は、このソリューションが実現可能であることを疑います。
を、ちょうど明確にするために、マクロの目標は、テンプレートの特殊化の定義を生成することで、 *現場では 'boost :: any'を変換しませんか? – Quentin
あなたはそれを持っています。マクロは上記のコードを生成します。 – Aleph0