用于复制/转换对象的一系列函数的模板

时间:2016-12-18 20:29:36

标签: c++ c++11 templates

我想编写一个名为copy的复制/转换函数系列,它从对象A复制到对象B.例如

void f(const A& a) {
  B b = copy<B>(a);
  ...
}

例如,A可以是std::array<double, 5>,B可以是std::vector<double>

是否可以执行此类操作并定义一次从任何std::array<T, n>转换为std::vector<T>的特化?在另一个文件中,我还想定义一次从任意std::array<T, n>转换为CudaVector<T>的特化。在另一个文件中,我想定义从SparseMatrix<T>DenseMatrix<T>的转换等等......

如果你没有找到任何解决方案,你是否考虑过任何类似的方法,只要我仍然有价值语义(我不想定义copy(const A& input, B& output))。

1 个答案:

答案 0 :(得分:1)

由于template argument deduction,这当然是可能的。 from-type可以从参数中推导出来,返回类型需要明确说明。

还有另外一个问题,即如果计划要将各种容器转换为各种其他容器,则需要部分功能特化,这是不允许的。但是通常的技巧可以解决使用类的部分特化的问题。

例如,这可用作通用模板及其专门用于将std::array复制转换为相同元素类型的std::vector

template<typename B, typename A>
struct copier {
  //static B copy(const A&); // Is there a generic fall-back algorithm? Probably not.
};

template<typename T, size_t N>
struct copier<std::vector<int>, std::array<T, N>> {
  static std::vector<int> copy(const std::array<T, N>& a) {
    std::vector<int> b{};
    std::copy(a.begin(), a.end(), std::back_inserter(b));
    return b;
  }
};

template<typename B, typename A>
B mcopy(const A& a) {
  return copier<B, A>::copy(a);
}

然后你可以使用

来调用它
std::array<int, 3> a{1, 2, 3};
using B = std::vector<int>;
B b = mcopy<B>(a);

看起来就像你问题中的那一行。

请注意copy不是这个功能的好名字。只要std::copy类型位于名称空间A中,ADL就会启动std,这可能会导致非常奇怪的错误消息。