模板构造函数

时间:2016-05-02 09:04:15

标签: c++

问题:我发现自己面临着许多重复的功能,以支持不同类型的几乎相同的类似数组的输入。例如,函数foo可能在以下版本中可用:

void foo (int v); // single value, 99% of all use cases.
void foo (std::initializer_list<int> v);
void foo (const std::vector<int> &v);
void foo (int *v, int size);

这种重复困扰我。我想有一个单独的函数foo,可以使用任何类型的数组类型调用(单个值显然被视为大小为1的数组)。

可能的解决方案包括:

  • 始终使用矢量版本。这会在每次使用时产生一些内存分配开销,并且由于99%的使用是针对单个值的,我发现这是不合需要的。
  • 有一个指定迭代器对的接口。尝试将函数调用为单个值时,这又会失败。
  • 对类似数据的数据进行某种抽象,可以处理所有需要的输入类型。这是一种很有前途的方法,但我遇到了一些麻烦......

我的实现称为mem_range,它提供了一个类似矢量的接口(显然只包括不改变矢量大小的操作)。应该通过mem_range的不同构造函数来处理各种类型的数组。

我无法指定应该采用std :: array的构造函数。问题是数组大小,这是模板定义的一部分 - 我无法弄清楚如何创建一个接受任何大小的数组的构造函数。

template<typename T>
class mem_range {
    public:
        mem_range (T *begin, T *end) { } // ok
        mem_range (std::vector<T> &vec) { } // ok

        template<int array_size>
        mem_range<array_size> (std::array<T, array_size> &arr) { } // not ok
}

最后一个构造函数产生&#34;错误C2988:无法识别的模板声明/定义&#34;在MSVC2015上。我现在经历了很多变化,但没有任何让编译器满意的事情。

为了清楚起见,根据答案,我已经在stackoverflow上阅读了类似的问题:

  • 以任何方式调整类数据数据的大小不在范围内。如果我想要这种能力,我只需传递一个std :: vector。
  • 我知道有很多类似标题的问题。这些似乎都没有得到合适的答案,通常不会超过&#34;为什么你想要这个?&#34;。

我试图在MSVC2015和现代GCC上完成这项工作,所以C ++ 14/17很好(据支持)。

2 个答案:

答案 0 :(得分:3)

在声明模板化构造函数时,模板被理解为属于构造函数,因此您无需在那里指定它。

您在数组参数后也缺少右括号>

所以构造函数应该如下所示:

template<int array_size>
mem_range(std::array<T, array_size>) { }

当然,您应该考虑将数组对象作为对常量的引用传递,并使用正确的类型(参见例如this std::array reference`),即

template<std::size_t array_size>
mem_range(std::array<T, array_size> const&) { }

答案 1 :(得分:0)

您可以使array_size成为模板类的可选值。

template<typename T, int array_size=0>
class mem_range {
public:
    mem_range (T *begin, T *end) { } // ok
    mem_range (std::vector<T> &vec) { } // ok
    mem_range (std::array<T, array_size> &array) { }
}