假设您有一个 boost::any
对象和一个 boost::variant
对象。
我正在寻找通用函数 convert
, 这需要一个模板参数 T 是一个专门的 boost::variant
例如boost::variant<int, std::string>
并神奇地转换 boost::any
到给定 boost::variant
的可用类型之一.
template<T>
T convert(const boost::any& any) {
// Some generic conversion code here or throw exception if conversion is not possible!
}
int main(int argc, char** args) {
typedef boost::variant<int, std::string> TVar;
boost::any any="Hello World";
TVar variant=convert<TVar>(any);
// variant contains "Hello World"
return 0;
}
我想知道是否可以编写这样的函数,或者是否由于某种原因不可能?
最佳答案
让我们将所有代码包含在由变体类型模板化的结构中
template<class VAR>
struct ExtractorGenerator
{
using Extractor = std::function<boost::optional<VAR>(boost::any const &)>;
std::vector<Extractor> extractors;
template<class T>
static boost::optional<VAR> tryCast(boost::any const & arg);
template<class T>
void operator()(T);
};
您可以轻松编写一个函数,尝试将给定类型的 boost::any 转换为该类型的变体
template<class VAR>
template<class T>
boost::optional<VAR> ExtractorGenerator<VAR>::tryCast(boost::any const & arg)
{
T const * val = boost::any_cast<T>(&arg);
return val == nullptr ? boost::none : boost::make_optional(VAR{*val});
}
现在使用 boost::mpl 你可以遍历所有变体类型来为每个变体类型生成函数
template<class VAR>
template<class T> void ExtractorGenerator<VAR>::operator()(T)
{
extractors.push_back(Extractor::tryCast<T>);
}
typedef boost::variant<int, std::string, char> MyVariant;
ExtractorGenerator<MyVariant> generator;
boost::mpl::for_each<MyVariant::types>(boost::ref(generator));
现在您只需应用所有创建的函数:
std::vector<MyVariant> extractedVals;
for (auto fun : extractor.extractors)
{
boost::optional<MyVariant> extracted = fun(val);
if (extracted)
extractedVals.push_back(extracted.get());
}
关于c++ - 将 boost::any 转换为 boost::variant 的通用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35357614/