Search code examples
c++loopsc++11inline

Range-based loop & Inline functions


I have here this code.

#include <iostream>
using namespace std;

template <typename T> inline T bigArry(const T data[5])
{
    T level = data[0];
    for(T item : data) // error C2143: syntax error : missing ',' before ':' (1st)
    { //error C2143: syntax error : missing ';' before '{' (3rd)
        if(level<item){ level=item; }
    }
    return  level;
}

int main()
{
    int data[5]={//five variables}
    cout << bigArry(data);//see reference to function template instantiation 'T bigArry<int>(const T [])' being compiled with [ T=int] (2nd)

    return 0;
}

The function bigArry() returns the highest value out of a array of 5 elements.

The problem is that when I use the range-based loop it gives me the errors mentioned in the code. But when I use the usual for, everything goes back to normal. I mean, the syntax to me looks fine, I can't see the problem. I'm using Visual Studio 2010.

The other thing I want to ask is about the inline functions. Currently I'm reading C++ Primer Plus 6th edition. When do I know when a function is too big to be inlined? Is there a standard of how short the code should be? Or, do we use the inline functions when we "think" it's okay?


Solution

  • The parameter data is NOT an array in your function template. It is actually a pointer.

    This function

    template <typename T> inline T bigArry(const T data[5])
    

    is exactly same as this:

    template <typename T> inline T bigArry(const T *data)
    

    There is NO difference at all.

    That is the reason why your code gives compilation error.

    There're couple of fixes here:

    • You could accept the argument by reference, as:

      template <typename T> 
      inline T bigArry(const T (&data)[5]) //NOTE &
      

      That should work. But then that looks cumbersome. Maybe, use the next.

    • Or you could use this (as suggested by @yzt):

      template <typename C> 
      inline auto bigArry(C const & data) -> decltype(data[0])
      

      This is clean as well as more flexible than the above one (and the below one). In addition to passing arrays, you could pass any container as long as data[0] is well-defined and means what it supposed to mean.

    • Or if you wish, you could use std::array<T, 5> as:

      template <typename T> 
      inline T bigArry(const std::array<T,5> & data) 
      

    Hope that helps.