c++ - 将 boost::any 转换为 boost::variant 的通用函数

标签 c++ templates boost boost-variant boost-any

假设您有一个 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/

相关文章:

c++ - 如何将 C++17 stdc++fs 库链接到混合语言(C++ 和 Fortran)CMake 项目?

c++ - Clang AST Matcher和AST Visitor之间有什么区别?

c++ - 多维数组 (C++)

c++ - Typedef 泛化

python - 在一个共享对象中 boost python 多个模块

c++ - 谁能告诉我在 Visual Studio 2010 上安装 Boost.iostreams 的最简单方法是什么?

c++ - QSqlQuery 内存问题。 QSqlQuery::exec() 和 QSqlDatabase::open()/close();

asp.net - 中央 HTML 模板可防止 ASP.NET MVC 中出现重复的演示代码

c++ - 模板的选择性编译

c++ - 为什么 Eigen 不需要模板关键字来使用 Matrix 的模板函数调用?