2

Since I don't know the size of the array, so I am using size as a parameter to pass into my function.

this works:

#include <cstddef>
#include <iostream>

template<class T, size_t N>
void takeArrayParam(T (&myArray)[N]) {
    for(auto i = std::begin(myArray); i != std::end(myArray); i++) {
        std::cout << *i << std::endl;
    }
}

int main() {
    int coolArray[10] = {1,2,3,4,5,6,7,8,9,10};
    takeArrayParam<int, 10>(coolArray);
    return 0;
}

and this doesn't work (compiler error):

#include <cstddef>
#include <iostream>

template<class T, size_t N>
void takeArrayParam(T (&myArray)[N]) {
    for(auto i = std::begin(myArray); i != std::end(myArray); i++) {
        std::cout << *i << std::endl;
    }
}

int main() {
    size_t size = 10;
    int coolArray[size];
    //int coolArray[10] = {1,2,3,4,5,6,7,8,9,10};
    takeArrayParam<int, size>(coolArray);
    return 0;
}

The difference: coolArray[10] vs. coolArray[size].

Thanks...

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
Jason Park
  • 33
  • 5

2 Answers2

3

You need to add const to your size definition in main().
That's because the size of an array that is allocated on the stack needs to be known at compile time.

Axalo
  • 2,953
  • 4
  • 25
  • 39
  • The size of any array needs to be known at the time of its definition. And any template argument needs to be a compile-time constant, regardless of what it's used for. – Potatoswatter Jan 29 '15 at 05:00
2

The problem is that size is not a constant expression(known at compile time), in your case declaring it using const or constexpr would fix your issue:

constexpr size_t size = 10;

Using const works in this case since you are initializing with a literal 10 which is a constant expression. This is covered in the draft C++ standard section 5.19 expr.const which says:

A conditional-expression is a core constant expression unless it involves one of the following as a potentially evaluated subexpression

and includes the following bullet:

an lvalue-to-rvalue conversion (4.1) unless it is applied to

  • a glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression, or

Note that array sizes must also be constant expressions:

int coolArray[size];
              ^^^^

As I cover in my answer to Does “int size = 10;” yield a constant expression? several compilers support variable length arrays(VLA) which is a C99 feature as an extension in C++ but it is not portable, notably Visual Studio does not support VLA.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • What are the cases in which a const variable is a constant expression? – David G Jan 29 '15 at 05:06
  • @0x499602D2 I updated my answer to cover this specific case, I cover the more general case of integral constant expressions in my [answer here](http://stackoverflow.com/a/21273849/1708801) – Shafik Yaghmour Jan 29 '15 at 05:21