我是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;
};
答案 0 :(得分:1)
是的,使用Boost.Variant是合理的。但是,你根本不需要使用指针;代替:
boost::variant<Column<int>, Column<float>, Column<std::string>>
答案 1 :(得分:1)
如果变体适合您的用例:
您可以将设计切换为更像
的设计Column<boost::variant<int, float, std::string>>
而不是
您可以从类型列表中生成变体:
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