Consider the following class template:
template<class T, std::size_t S, SomeEnum = SomeEnum::NOT_DYNAMIC>
class Foo {
Where SomeEnum would be defined as
class SomeEnum { NOT_DYNAMIC, DYNAMIC };
This class has a private std::array
, but based on the value passed by the user to SomeEnum, I would like to instead use std::vector
. For example, if the user passes SomeEnum::DYNAMIC
, I would use std::vector
instead of std::array
. This would be implemented through std::conditional_t
and [[no_unique_address]]
.
I am wondering if there is a way to "remove" the non-type template parameter S
, in case the user passed SomeEnum::DYNAMIC
. This is to avoid having the user type a size, when it is unnecessary because the underlying contaier is std::vector
. Meanwhile, I need to keep the S
parameter in case the user does not pass anything to SomeEnum
, because std::array
requires the size too.
Is it possible with some trickery, and if not, how would I solve this?
Current thoughts:
- Using std::conditional_t as explained,
- Using inheritance, or using a specialization (not yet attempted or thought of)
- Polymorphism is NOT an option
CodePudding user response:
A similar situation in the standard library exists with std::span<T, N>
or std::span<T>
: Omitting the template parameter entirely defaults the size to std::dynamic_extent
((std::size_t) -1
), which you can use to have a std::vector
instead of a std::array
:
template<class T, std::size_t S = std::dynamic_extent>
class Foo {
private:
std::conditional_t<(S == std::dynamic_extent), std::vector<T>, std::array<T, S>> container;
};