将构造函数参数变成模板参数

Make a constructor parameter into a template parameter

我有一个自制的环形缓冲器 class 像这样:

template<typename T, int maxElements>
class RingBuffer
{
};

class Foo
{
    RingBuffer<int, 2000> ring;
};

这是一个性能瓶颈,因为用 boost::circular_buffer 快速替换显示整体代码节省了 7%。但是,我需要像这样显式构造 boost::circular_buffer

class Foo
{
    boost::circular_buffer<int> ring;
public:
    Foo() : ring(2000) {}
};

有没有一个简洁的成语(或者实际上是另一个 Boost 模板!)我可以用 boost::circular_buffer 来表示这样的话:

class Foo
{
    auto_construct<boost::circular_buffer<int>, 2000> ring;
};

所以我不再需要触摸 Foo::Foo()?

更新:尽管在-class初始化程序接近,我也有typedefs:

using Ring200 = RingBuffer<int, 2000>;

所以我想:

using BoostRing2000 = auto_construct<boost::circular_buffer<int>, 2000>;

这样我就不需要在每次声明时都记住 {2000}

一个默认的成员初始化器就可以做到。

class Foo
{
    boost::circular_buffer<int> ring{2000};
};

假设您的意图是仅触摸成员定义。它还具有这样的优势,即如果您对特定的构造函数改变主意,修改起来并不麻烦。只需向该 c'tor 添加一个成员初始值设定项即可。


鉴于编辑,我对 boost 中的任何内容都不熟悉,可以做你想做的事。但是另一种方法,也可以为您节省一些替代,是将您的自制 RingBuffer 实现为 boost::circular_buffer 的薄包装。

template<typename T, int maxElements>
class RingBuffer : boost::circular_buffer<T> // Can also be a member instead of privately inherited
{
  // Now pull what we need with using delcarations and define a c'tor

   public:

   RingBuffer() : boost::circular_buffer<T>(maxElements) {}
};

您仍然可以将 in-class 初始化程序与非类型模板参数一起用于 Foo 包装器。

template <std::size_t N> struct Foo {
   boost::circular_buffer<int> ring{N};
};

适当的类型别名是

using BoostRing2000 = Foo<2000>;

如果希望保持存储数据的实际类型灵活,您可以添加另一个模板参数,这样

template <class T, std::size_t N> struct Foo {
   boost::circular_buffer<T> ring{N};
};

允许对类型别名进行细粒度控制,例如

using BoostIntRing2000 = Foo<int, 200>;
template <class T> using BoostRing2000 = Foo<T, 200>;

实例化现在为

BoostIntRing2000 someIntegerRing;
BoostRing2000<double> someDoubleRing;