2009-10-28 34 views
2

鉴于:传递的std ::矢量为任何类型的功能

template<typename T> class A { 
    B b; 
    std::vector<T> vec1; 
    std::vector<T> vec2; 
} 

我想B到具有填充一个成员函数(),它于那些参考矢量,并用值填充VEC2 T取决于b中包含的一些信息。这样做的
一种方法是超载填写()为每个可能的参数T:

fill(const std::vector<float>& a, std::vector<float>& b) 

等等,但是这将意味着很多不必要的重复的操作对于每一个可能的T.内的同fill()我可以使用vector :: value_type进行计算,但是我不知道如何以这种方式声明它需要使用各种std :: vector。显而易见的方法是使用模板的免费功能。有没有更简单的方法来做到这一点?

回答

5

模板化B.

template<typename T> class B { 
    void fill(const std::vector<T>& a, std::vector<T>& b) { } 
}; 

template<typename T> class A { 
    B<T> b; 
    std::vector<T> vec1; 
    std::vector<T> vec2; 
} 

如果你不想模板化B,然后模板化填充功能:

class B { 
    template<typename T> 
    void fill(const std::vector<T>& a, std::vector<T>& b) {} 
}; 
+1

更多信息:B是纯虚函数的继承层次结构的一部分,并且包含在一个智能指针指向基类中。 用户需要实例化与A相同类型的B(这会增加错误的可能性),对于类的用户来说不会很明显,所以我宁愿避免这种情况。 – pmr 2009-10-28 23:36:16

+0

我意识到重构大层次结构是一种痛苦,但是您也可能尝试使用策略类作为模板参数,而不是传入智能指针,并显然(基于您的描述)牺牲类型安全性来提高灵活性。 – 2009-10-28 23:48:24

4

模板化fill

class B { 
public: 
    template<typename T> 
    void fill(const std::vector<T>& a, std::vector<T>& b) 
    { /*...*/ } 
    //... 
}; 

(从你说明它看到b应该是const std::vector<T>&。)

2

您可以定义B中的模板类,填充为模板的功能,或者我最喜欢的(非模板类的内部B),使用标准std::transform/std::copy/std::fill,这已经是模板函数,来填充载体。
(全部位于<algorithm>标题内)。

+0

不知道非模板类中的模板成员函数。迄今为止最好的选择与std :: transform。 – pmr 2009-10-28 23:38:14

5

你已经得到了很多答案,但我至少在某种程度上不同意他们。我的直接反应是你根本不应该通过载体b::fill。相反,你应该传递一个迭代器(或者可能是一对迭代器)。其余大部分都是正确的:这仍然意味着fill应该是模板成员函数。当你打电话时,你可能想要通过一个std::back_insert_iterator,通常通过std::back_inserter获得。你所说的内容

部分似乎自相矛盾的是:如果b::fill修改vec1vec2,他们或许应该被作为常量引用传递。无可否认,const在应用于容器时并不完全具有其通常的含义,但事实仍然是将对const的引用传递给一个函数,该函数的唯一目的显然是修改传递的内容似乎是错误的。

+1

同意我同意你应该传递迭代器范围而不是容器的观点。他还应该检查迭代器类型的擦除。 Thomas Becker和Adobe公共图书馆一样有一个any_iterator类。 – 2009-10-28 23:48:55

+0

关于对const的引用:只有第二个向量将被修改。 关于使用迭代器:填充操作将会相当繁重(大量插入),它可以从vector :: reserve(int)中受益。我如何通过std :: back_inserter获得这种性能改进? – pmr 2009-10-28 23:56:46

+0

储备储备_space_(也是构造函数之一)。它不会创建对象。你可以使用reserve()而不是back_insert。它构造(或分配给)预分配空间的结果,这正是您想要的。 (并且,对于具有较大构造和光照分配的对象,您可以创建具有所需大小的矢量,而不使用back_inserter) – 2009-10-29 00:08:45

相关问题