利用 boost-variant 创建带有 boost::mpl::for_each 的通用工厂方法

Posted

技术标签:

【中文标题】利用 boost-variant 创建带有 boost::mpl::for_each 的通用工厂方法【英文标题】:Utilize boost-variant to create generic factory method with boost::mpl::for_each 【发布时间】:2016-09-08 06:33:36 【问题描述】:

在我的一个项目中,我需要将 boost::variant which()-Function 的 int 映射到 boost::variant 的类型。

由于某些原因,地图不包含正确的 TVar 类型?这是为什么呢?

#include <boost/mpl/for_each.hpp>
#include <boost/variant.hpp>
#include <string>
#include <map>
#include <iostream>

using TVar = boost::variant<std::string, int, double>;

namespace Helper 
    struct createMap 
        std::map<int, TVar> map;
        template<typename T>
        void operator()(const T& t) 
            auto x = TVar(t);
            map[x.which()] = x;
        
    ;



bool createObject(int which, TVar& var) 
    Helper::createMap c;
    boost::mpl::for_each<TVar::types>(boost::ref(c));
    if (c.map.find(which) != c.map.end()) 
        var = c.map[which];
        return true;
    
    else 
        return false;
    


int main() 
    TVar var;
    bool ok=createObject(0, var);
    return 0;

【问题讨论】:

通过值或引用传递参数。 另外,每次调用createObject 时都会创建一个新地图。这是设计使然吗? 谢谢。如此简单... :-( 我更正了代码。现在地图已填满,但不幸的是条目不正确。地图始终包含一个包含 std::string 的 boost::variant。 又傻了。将 == 替换为 =。现在它起作用了。非常感谢。我也许应该删除这个问题。 :-( 我每次都为第一种方法创建了一张地图。如果只有很少的电话,就没有问题。 :-) 【参考方案1】:

如果我理解正确,您想为变体分配某种类型的默认构造值,该类型将在运行时通过索引变体的可能类型来确定,那么您正在寻找这个:

#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>

#include <boost/variant.hpp>
#include <string>


template <typename VariantT, int L, int R>
struct assign_default_constructed

    static bool call(int which, VariantT& var)
    
        static int const M = L + (R - L + 1) / 2;
        if (which < M) 
            return assign_default_constructed<VariantT, L, M - 1>::call(which, var);
        
        else 
            return assign_default_constructed<VariantT, M, R>::call(which, var);
        
    
;

template <typename VariantT, int I>
struct assign_default_constructed<VariantT, I, I>

    static bool call(int /*which*/, VariantT& var)
    
        //assert(which == I);
        var = typename boost::mpl::at_c<typename VariantT::types, I>::type();
        return true;
    
;

template <typename VariantT>
bool createObject(int which, VariantT& var)

    static int const N = boost::mpl::size<typename VariantT::types>::value;
    if (which < 0 || which >= N) return false;
    return assign_default_constructed<VariantT, 0, N - 1>::call(which, var);


int main() 
    boost::variant<std::string, int, double> var;
    bool ok = createObject(1, var);
    return ok ? var.which() : -1;

【讨论】:

以上是关于利用 boost-variant 创建带有 boost::mpl::for_each 的通用工厂方法的主要内容,如果未能解决你的问题,请参考以下文章

spring boo的简单搭建(eclipse+springboot + redis + mysql + thymeleaf)

Gradle:带有用于 Spring Boot 的 jvm 参数的自定义任务

JavaScript函数声明提升

利用docker制作一个带有redis软件的镜像,供其他人使用

除非选中,否则带有 BooleanField 的 Django 表单始终无效

2022-10-04:以下go语言代码输出什么?A:{123} main.T{x:123} B:{123} T{x:123} C:boo boo D:boo main.T{x:123}。 packag