在我的項目中我詳盡地使用了boost::any
和boost::variant
。爲此,我在前一個問題Generic function to convert boost::any to boost::variant中設計了一個從boost::any
到boost::variant
的常規轉換程序。非常感謝幫助我的人們。提升任何使用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