vector <模板>,c++,类,添加到向量

4
我正在尝试创建一个类,该类将从一组向量中绘制元素(并且还将这些向量作为容器存储在类内部),但是当管理向量时,使用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
}

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

如果您有多个容器变量,则需要多个函数来添加它们。现在没有办法知道从类型中选择哪个变量。 - Some programmer dude
由于已经被踩了,所以我在搜索答案,但我找到的都是如何在模板中返回2种不同类型的内容。 - qubits
可以做的是,让所有包含的类型(例如你示例中的'Chocolate'和'Sugar')都继承自相同的虚基类,这样你只需要一个容器。 - Some programmer dude
可能是 http://stackoverflow.com/questions/20927455/how-to-mimic-template-variable-declaration/20927537#comment31422993_20927537 的重复问题。 - Jarod42
2个回答

6

在向向量中添加元素时,使用诸如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<T>(),但你得到了我的 +1。 - StoryTeller - Unslander Monica
你仍然需要针对每个容器编写一个 get_vector 函数。只是公共接口更加清晰。 - Some programmer dude
@JoachimPileborg,这就是重点:如果您需要在公共接口中添加新功能(例如糖和巧克力的count),则可以使用相同的get_vector原语实现它,只需一个(类似模板的)实现即可。 - utnapistim
1
你甚至可以将向量存储在boost::fusion::map中,这样你就不再需要实现get_vector了。 - Drax

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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接