我应该在具有不同类型参数的类中使用Boost Variant

时间:2014-12-29 00:45:05

标签: c++ boost

我是C ++的新手,我不确定建模类来表示列表的最佳方法;其中一个列是一个带有名称(字符串)的STL向量的包装器,并且应该是  Column<int>Column<float>Column<std::string>

目前我已将其硬编码为Column<int>,但需要支持Column<float>Column<std::string>

我应该沿着提升变体路线(也称为标记联盟)?

boost::variant<Column<int>*, Column<float>*, Column<std::string>*>

不确定是否有更好的解决方案,因为它只是不同的类型参数。

我很感激C ++众神分享他们的智慧。

template <typename T>
class Column
{
public:
    Column(std::string& name, std::vector<T>& vec) : name(name), vec(vec) {}
    T& at(const size_t i) { return vec[i]; }
private:
    std::string name;
    std::vector<T> vec;
};

class Table
{
public:
    Table(std::string& name) : name{name} {}

    void addColumn(Column<int>* vec) 
    {
        columns.push_back(vec);
    }

    Column<int>*& getColumn(const size_t i)
    {
        return columns[i];
    }
private:
    std::string name;
    std::vector<Column<int>*> columns;
};

2 个答案:

答案 0 :(得分:1)

是的,使用Boost.Variant是合理的。但是,你根本不需要使用指针;代替:

boost::variant<Column<int>, Column<float>, Column<std::string>>

答案 1 :(得分:1)

如果变体适合您的用例:确定!模板实例只是类型。

  1. 您可以将设计切换为更像

    的设计
    Column<boost::variant<int, float, std::string>>
    

    而不是

  2. 您可以从类型列表中生成变体:

    column_variant<int, float, std::string>
    

    在c ++ 11中,这是微不足道的:

    <强> Live On Coliru

    template <typename... Ts>
    using make_column_variant = typename boost::make_variant_over<boost::mpl::vector<Column<Ts>...>>::type;
    

    这是c ++ 03版本:

    <强> Live On Coliru

    #include <boost/variant.hpp>
    #include <boost/mpl/vector.hpp>
    #include <iostream>
    
    template <typename T> struct Column { 
        T v; 
        Column(T const& v) : v(v) {}
        friend std::ostream& operator<<(std::ostream& os, Column<T> const& cv) {
            return os << cv.v;
        }
    };
    
    /* c++03 helper */
    namespace mpl = boost::mpl;
    
    template <typename Seq>
    struct make_column_variant
    {
        typedef typename mpl::transform<
            Seq, 
            Column<mpl::_1>,
            mpl::back_inserter<mpl::vector<> > 
        >::type columns;
    
        typedef typename boost::make_variant_over<columns>::type type;
    };
    
    int main() {
        make_column_variant<mpl::vector<int, float, std::string> >::type v(std::string("hello world"));
        std::cout << v;
    }
    

    这在C ++ 11

  3. 中要短得多