将构造函数参数变成模板参数
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初始化程序接近,我也有typedef
s:
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;
我有一个自制的环形缓冲器 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初始化程序接近,我也有typedef
s:
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;