处理类和类*的模板函数

template function to handle class and class*

本文关键字:函数 处理      更新时间:2023-10-16

下面的代码允许我模板化一个函数接受一个形参,形参是指向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>>

也许是在boost中?

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

为什么我问这个问题:我有一个应用程序的两个函数实现几乎相同的逻辑。一个接受一个someeclass的列表,另一个接受一个指向someeclass的指针向量。我目前正计划重构代码,用指向SomeClass的共享指针列表替换SomeClass列表。但我这样做的唯一原因是将逻辑移动到公共实现。如果有一种完全合理的方法可以避免,我就不想这么做。

如果我正确理解了你的问题,你可以使用如下的解引用机制:

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

,然后调用你的数据,如:

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

现场演示

p。你还必须定义:

template <>
struct is_box_containter <std::vector<Box>> {
    enum { value = true };
};
template <>
struct is_box_containter <std::vector<std::reference_wrapper<Box>>> {
    enum { value = true };
};