3

I am learning templates in C++ using the books listed here. So trying out(writing) different examples to clear my concepts. In particular, i learned that we can use templates to pass array by reference as shown below:

#include <iostream>
template<unsigned int N>
void printSize(double (&arr)[N])
{
    std::cout<<"size is: "<<N<<std::endl;
}
int main()
{
    double arr1[] = {1,2,3};
    printSize(arr1); //this works as expected 
}

The above is just a contrived example which i understand. While the example given below, i am unable to understand.

#include <iostream>
template<unsigned int N>
void printSizeTwo(double (&arr)[N+1]) //is this valid? I mean what will N+1 mean here if it is indeed valid.
{
    std::cout<<"size is: "<<N<<std::endl;
}
int main()
{
    double arr1[] = {1,2,3};
    printSizeTwo(arr1); //why doesn't this call work?
    
}

My question is that in my second code snippet, is writing N+1 valid? If yes, then what does it mean that is., how is it different from the first code snippet where we have only N instead of N+1. Basically, i want to understand why the call to printSizeTwo(arr1) doesn't work and how can i make it work.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • 7
    `N+1` is valid, but it's a non-deduced context - the compiler cannot infer `N` automatically from the call. You can provide `N` explicitly: `printSizeTwo<2>(arr1);` (though of course this rather defeats the purpose of this particular function). The standard doesn't require compilers to solve arithmetic problems, like "what should `N` be to make `N+1 == 3`". – Igor Tandetnik Jan 28 '22 at 15:05
  • Ok then i guess i should delete this question. – Jason Jan 28 '22 at 15:23
  • @IgorTandetnik So is there any reason for allowing this. I mean is it useful anywhere? – Jason Jan 28 '22 at 15:28
  • 2
    Please don't delete the question. There's nothing wrong with it. – cigien Jan 28 '22 at 15:29
  • @cigien Ok not deleting. – Jason Jan 28 '22 at 15:33
  • 2
    A reason for allowing arithmetic on template parameters? Well, consider something like `template void concatenate(double (&first)[N], double (&second)[M], double (&out)[N + M]);` – Igor Tandetnik Jan 28 '22 at 15:39
  • 3
    @IgorTandetnik If there isn't a reasonable duplicate target, perhaps you could post your comments as an answer? – cigien Jan 28 '22 at 15:48

0 Answers0