下面的代码允许我模板化一个功能 将一个参数作为Box对象的三种不同指针类型之一的向量:
const std::vector<std::shared_ptr<Box>>&
const std::vector<std::weak_ptr<Box>>&
const std::vector<Box*>&
有没有办法将其扩展为支持:
const vector<Box>&
const vector<std::reference_wrapper<Box>>
或许是什么促进?
#include <vector>
#include <iostream>
class Box{
public:
Box (unsigned int id, unsigned int side): id(id), side(side){}
int volume(){
return side * side * side;
}
unsigned int id;
unsigned int side;
};
template <typename T>
struct is_box_containter {
enum { value = false };
};
template <>
struct is_box_containter <std::vector<std::shared_ptr<Box>>> {
enum { value = true };
};
template <>
struct is_box_containter <std::vector<std::weak_ptr<Box>>> {
enum { value = true };
};
template <>
struct is_box_containter <std::vector<Box*>> {
enum { value = true };
};
template <typename T>
typename std::enable_if<is_box_containter<T>::value>::type
measure(T const& boxes )
{
for (auto& box : boxes) {
std::cout << box->id << " has volume " << box->volume() << std::endl;
}
}
int main (){
std::vector<std::shared_ptr<Box>> some_boxes;
some_boxes.push_back(std::shared_ptr<Box>(new Box(1,4)));
some_boxes.emplace_back(new Box(2, 12));
Box * box_3 = new Box(3, 8);
Box * box_4 = new Box(4, 9);
std::vector<Box*> more_boxes;
more_boxes.emplace_back(box_3);
more_boxes.emplace_back(box_4);
measure(some_boxes);
measure(more_boxes);
return 0;
}
为什么我问这个问题: 我有一个应用程序,有两个函数实现几乎相同的逻辑。一个是SomeClass的列表,另一个是SomeClass的指针向量。 我目前正在计划重构代码以使用SomeClass的共享指针列表替换SomeClass列表。但我这样做的唯一原因是将逻辑移到一个通用的实现。如果有一种完全合理的方法可以避免,我不想这样做。
答案 0 :(得分:4)
如果我理解你的问题,你可以使用如下的解除引用机制:
public static void main(String[] args) {
Integer[] numbers = {1,2,3,4,5,6,7,8,9,10};
List<Integer> list = new ArrayList<Integer>(numbers.length);
for(int i = 0;i<numbers.length;++i) {
list.add(i);
}
}
private static int returnRandomNumber(List<Integer> list) {
Random r = new Random();
if(list.size() == 0) {
return -1; // maybe throw an exception
}
int index = r.nextInt(list.size());
int number = list.get(index);
list.remove(index);
return number;
}
然后调用您的数据:
template<typename T>
T& dereference(T &v) {
return v;
}
template<typename T>
const T& dereference(const T& v) {
return v;
}
template<typename T>
typename std::enable_if<!std::is_function<T>::value, T&>::type dereference(T* v) {
return dereference(*v);
}
template<typename T>
const T& dereference(const std::shared_ptr<T>& v) {
return dereference(*v);
}
template<typename T>
const T& dereference(const std::weak_ptr<T>& v) {
return dereference(*v);
}
template<typename T>
const T& dereference(const std::reference_wrapper<T>& v) {
return v;
}
P.S你还必须定义:
template <typename T>
typename std::enable_if<is_box_containter<T>::value>::type
measure(T const& boxes )
{
for (auto& box : boxes) {
std::cout << dereference(box).id
<< " has volume " << dereference(box).volume() << std::endl;
}
}