【问题标题】:vector <template>, c++, class, adding to vectorvector <模板>,c++,类,添加到向量
【发布时间】:2014-01-25 03:31:25
【问题描述】:

我正在尝试创建一个类,该类将从一组向量中绘制元素(并且还将这些向量作为类中的容器保存),但我觉得在管理具有很多函数的向量时,例如使用了 vectorOneAdd、vectorTwoAdd为了向向量添加元素是没有意义的。一定有更好的方法,这就是我在这里问的原因,我听说你可以使用模板来做到这一点,但我不太确定如何。需要帮助。不想有很多无意义的代码。

我的意思的例子如下:

class Cookie
{
std::vector<Chocolate> chocolateContainer;
std::vector<Sugar> sugarContainer;

void chocolateVectorAdd(Chocolate element);    // first function adding to one vector
void sugarVectorAdd(Sugar element);   // second function adding to another vector
}

请使用示例代码,谢谢:)

【问题讨论】:

  • 如果您有多个容器变量,则需要添加多个函数。现在无法确定从类型中选择哪些变量。
  • P.S 由于我已经被否决了,我正在寻找答案,但我发现的只是如何在模板中返回 2 种不同的类型。
  • 可以做的是让所有包含的类型(比如你的例子中的ChocolateSugar)继承同一个虚拟基类,那么你只需要一个容器。

标签: c++ templates vector


【解决方案1】:

有很多函数,比如vectorOneAdd、vectorTwoAdd,用来向向量添加元素是没有意义的。一定有更好的办法

有:

class Cookie {
    std::vector<Chocolate> chocolateContainer;
    std::vector<Sugar> sugarContainer;

private:
    template<typename T>
    std::vector<T>& get_vector(const T&); // not implemented but particularized

    // write one of these for each vector:
    template<>
    std::vector<Chocolate>& get_vector(const Chocolate&) { return chocolateVector; }
    template<>
    std::vector<Sugar>& get_vector(const Sugar&) { return sugarVector; }

public:
    template<typename T>
    void add(T element) {
        auto& v = get_vector(element);
        v.push_back(std::move(element));
    }
};

【讨论】:

  • 就我个人而言,我宁愿放弃未使用的参数并写完整的get_vector&lt;T&gt;(),但你得到了我的+1。
  • 您仍然需要为每个容器创建一个 get_vector 函数。只是公共界面更干净。
  • @JoachimPileborg,这就是重点:如果您需要公共接口中的新功能(例如,count 用于糖和巧克力),您可以在相同的get_vector 原语上实现它,使用单一(类似模板-d)实现。
  • 您甚至可以在boost::fusion::map 中处理向量,然后您将不再需要实现get_vector
【解决方案2】:

以下将解决您的问题(需要 C++11)

#if 1 // std::get<T>(tuple) is not in C++11

// Helper to retrieve index to be able to call std::get<N>(tuple)
template <typename T, typename ... Ts> struct get_index;

template <typename T, typename ... Ts>
struct get_index<T, T, Ts...> : std::integral_constant<std::size_t, 0> {};

template <typename T, typename Tail,  typename ... Ts>
struct get_index<T, Tail, Ts...> :
    std::integral_constant<std::size_t, 1 + get_index<T, Ts...>::value> {};
#endif

template <typename ... Ts>
class Data
{
public:
    template <typename T>
    void push_back(const T& x) { return getVector<T>().push_back(x); }

    template <typename T>
    std::size_t size() const { return getVector<T>().size(); }

private:
    template <typename T>
    const std::vector<T>& getVector() const { return std::get<get_index<T, Ts...>::value>(items); }

    template <typename T>
    std::vector<T>& getVector() { return std::get<get_index<T, Ts...>::value>(items); }
private:
    std::tuple<std::vector<Ts>...> items;
};

测试一下:

class A{};
class B{};

int main()
{
    Data<A, B> d;

    d.push_back(A());
    d.push_back(B());
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    • 2022-01-03
    • 2013-04-19
    • 2011-06-14
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    相关资源
    最近更新 更多