Archduke
Archduke

Reputation: 349

Class template overload based on presense of non-type parameter?

I have a templated class that works as such:

template <typename T, std::size_t maxSize>
class Foo
{
    std::array<T, maxSize> arr; 
};

I'd like to make an overload where you can choose to only pass T and instead get a vector as the underlying container:

template <typename T>
class Foo
{
    std::vector<T> arr; 
};

What's the proper way to do this?

Upvotes: 1

Views: 97

Answers (1)

parktomatomi
parktomatomi

Reputation: 4079

You can use a parameter pack for the size, and specialize on 1 argument or 0 arguments:

First, provide a default that fails to compile

template <typename T>
struct always_false : std::false_type {};

template <typename T, std::size_t... Is>
class Foo {
    static_assert(always_false<T>::value, "too many sizes");
};

Then, partially specialize for one or zero arguments:

template <typename T, std::size_t maxSize>
class Foo<T, maxSize> {
public:
    std::array<T, maxSize> arr;
};

template <typename T>
class Foo<T>
{
public:
    std::vector<T> arr;  
};

Demo: https://godbolt.org/z/5bW9c7

Upvotes: 4

Related Questions