1

Maybe the question in the title is too generic, and it is generic because I'm curious about

But this generic question sprung from a concrete, less generic use case.

I initially wrote a function dealing with an array of 2 elements of class A:

auto /* return type is not relevant */ fun(std::array<A,2>& a) {
    // ... do things...
}

then I decided to extend the functionality to the case that a has 3 elements. Handling this by using a std::vector<A> is not an option as the two scenarios never interact with each other and I never need to push_back on/pop_back from a.

To make the two of them work together, I gave up on the explicit parameter type and relied on auto:

auto /* ditto */ fun(auto& a) {
    // ... do things, which depend on `auto` having deduced a `std::array<A,N>` for some `N`...
}

Doing so however is a bit undesirable because:

  • the code is less self-documenting than it could be: someone else (or myself in a month) would have to go look inside fun in order to undestand that it uses a assuming that it is a std::array<A,N> for a general N;
  • the error messages are less clear than they could be: the error would be along the lines of no function matches this call, whereas I'd like the error to be this function works with std::array of As.

What I could do, is keep auto and static_asserting in the first line of the function that a be std::array<A,2> or std::array<A,3>, but in the future I might want to handle the case 4 too.

So I'm just wandering if there's a way to assert that a variable a is instance of a given template class, e.g. std::array, with not all template parameters specified.

In general, given a tempalte class like this,

template<typename A, int n, typename B, int m>
class C { /* impl */ };

is it possible to assert that a variable a is of type C<some_class,some_number,?,?>?

Enlico
  • 23,259
  • 6
  • 48
  • 102
  • 1
    It seems like your question is the same as [this](https://stackoverflow.com/questions/17390605) one. Or at least related. – cigien Nov 18 '20 at 15:40

1 Answers1

2

Just make your function a template. N will be deduced automatically.

template<std::size_t N>
auto fun(std::array<A,N>& a) {
   // ... do things, which depend on `auto` having deduced a `std::array<A,N>` for some `N`...
}
user253751
  • 57,427
  • 7
  • 48
  • 90
  • Does this work if `fun` is not a function but a lambda? Sorry, but in an attempt to simplify the question I forgot to specify _in my case `fun` is actually a lamda_. – Enlico Nov 18 '20 at 15:42
  • @Enrico everything you can do with lambdas, you can also do without lambdas, so maybe you can consider that. – user253751 Nov 18 '20 at 15:46
  • 1
    @Enrico Then, read this: https://stackoverflow.com/q/54126204/580083. – Daniel Langr Nov 18 '20 at 15:48
  • @DanielLangr, I'm accepting user253751's answer because it does answer my (kind of flawed) question. However, than you for linking that, which very very very useful to know. – Enlico Nov 18 '20 at 16:05
  • 1
    @Enrico - Starting from C++20 you can use template lambdas and write something `[](std::array & a){ /* .... */ }` – max66 Nov 18 '20 at 16:24