Reputation: 15009
I have a home-brew ring buffer class like this:
template<typename T, int maxElements>
class RingBuffer
{
};
class Foo
{
RingBuffer<int, 2000> ring;
};
This is a performance bottleneck, as a quick replacement with boost::circular_buffer
showed a 7% saving in the overall code. However, I need to explicitly construct the boost::circular_buffer
like this:
class Foo
{
boost::circular_buffer<int> ring;
public:
Foo() : ring(2000) {}
};
Is there a neat idiom (or indeed another Boost template!) that I can wrap boost::circular_buffer
with to say something like:
class Foo
{
auto_construct<boost::circular_buffer<int>, 2000> ring;
};
So I no longer need to touch the Foo::Foo()
?
Update: Although in-class initialisers get close, I also have typedef
s:
using Ring200 = RingBuffer<int, 2000>;
So I would like:
using BoostRing2000 = auto_construct<boost::circular_buffer<int>, 2000>;
So that I don't need to remember the {2000}
every time I declare one.
Upvotes: 1
Views: 88
Reputation: 38267
You can still use in-class initializers with a non-type template parameter for your Foo
wrapper.
template <std::size_t N> struct Foo {
boost::circular_buffer<int> ring{N};
};
And the appropriate type alias would be
using BoostRing2000 = Foo<2000>;
If it's desired to keep the actual type of the data stored flexible, you can add another template parameter such that
template <class T, std::size_t N> struct Foo {
boost::circular_buffer<T> ring{N};
};
which allows for fine grained control over the type aliases, e.g.
using BoostIntRing2000 = Foo<int, 200>;
template <class T> using BoostRing2000 = Foo<T, 200>;
and the instantiations now read
BoostIntRing2000 someIntegerRing;
BoostRing2000<double> someDoubleRing;
Upvotes: 2
Reputation: 170065
A default member initializer can do.
class Foo
{
boost::circular_buffer<int> ring{2000};
};
Assuming your intent is to only touch the member definition. It also carries the advantage that if you ever change your mind for a specific constructor, it's not a hassle to modify. Just add a member initializer to that c'tor and your'e done.
Given the edit, I'm unfamiliar with anything in boost
the can do what you are after. But another approach, that will also save you some substitution, is to implement your homebrewed RingBuffer
as a thin wrapper around 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) {}
};
Upvotes: 4