gangulo
gangulo

Reputation: 57

Default value for template constant in C++

I'm trying to replace a global buffer size to one that can be modifiable for tests. The current code is something like:

static const uint32_t BUFFER_SIZE = 1 << 8;

class BufferWrapper {
.
.
.

char buffer_[BUFFER_SIZE];
};

This causes a problem when I'm trying to change the BUFFER_SIZE for tests. Thus, I was hoping to make the BUFFER_SIZE a template constant, and having a default value for said constant so that I only need to specify it during tests, something like:

static const uint32_t BUFFER_SIZE = 1 << 8;

template <uint_32 SIZE = BUFFER_SIZE>
class BufferWrapper {
.
.
.

char buffer_[SIZE];
};

That way, previous declarations can still compile like:

BufferWrapper buf

But during a test, I could write something like this to test a buffer of 1KB:

BufferWrapper<1024> test_buf;

My question is, is it possible to provide a default for a template value, and how would I do it? The error I get with the above when I declare something like BufferWrapper buf; is:

error: use of class template 'BufferWrapper' requires template arguments; argument deduction not allowed in function prototype

Upvotes: 3

Views: 1708

Answers (2)

As this answer states, the code is fine since C++17. However, if you do not have access to that, you can still get around the need to change all existing code to use BufferWrapper<> instead of BufferWrapper.

Do this by renaming BufferWrapper to something else (e.g. BufferWrapperTemplate) and providing a type alias to the default-sized version:

template <uint_32 SIZE = BUFFER_SIZE>
class BufferWrapperTemplate {
.
.
.

char buffer_[SIZE];
};

typedef BufferWrapperTemplate<> BufferWrapper;

This way, all existing code can keep using BufferWrapper, and tests can use BufferWrapperTemplate<42> where needed.

Upvotes: 5

eerorika
eerorika

Reputation: 238361

There is no problem with the shown program in C++17.

Prior to C++17, you must provide the template argument list even if it is empty:

BufferWrapper<> test_buf;

In such case you can avoid changing the client code by using a type alias:

template <uint_32 SIZE = BUFFER_SIZE>
class BufferWrapperTemplate;

using BufferWrapper = BufferWrapperTemplate<>;

Upvotes: 4

Related Questions