使构造函数参数成为模板参数

时间:2018-08-23 07:31:53

标签: c++ boost idioms

我有一个自制的环形缓冲区类,

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()吗?

更新:尽管课堂上的初始化程序越来越接近,但我也有typedef s:

using Ring200 = RingBuffer<int, 2000>;

所以我想:

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

这样我就不必在每次声明{2000}时都记住它。

2 个答案:

答案 0 :(得分:4)

默认的成员初始化程序可以做到。

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

答案 1 :(得分:2)

对于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;