Range-based contours and built-in functions

I have 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 bigArry () function returns the highest value from an array of 5 elements.

The problem is that when I use a range-based loop, it gives me the errors mentioned in the code. But when I use the usual, everything returns to normal. I mean, the syntax looks good to me, I don't see a problem. I am using Visual Studio 2010.

Another thing I want to ask is the built-in functions. I am currently reading C ++ Primer Plus 6th Edition. When do I know when a function is too large to be built-in? Is there a standard for how shorter the code is? Or do we use built-in functions when we β€œthink” about it in order?

Thanks RobertEagle

+6
source share
2 answers

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

This function

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

exactly the same:

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

There is no difference whatsoever.

This is why your code gives a compilation error.

There are several fixes here:

  • You can take an argument by reference, for example:

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

    That should work. But then it looks bulky. Perhaps use the following.

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

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

    It is clean as well as more flexible than the above (and below). In addition to passing arrays, you can pass any container if data[0] is clearly defined and means what it should mean.

  • Or, if you want, you can use std::array<T, 5> as:

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

Hope this helps.

+7
source

This is because array types decay into pointers when using a function as parameters or when they are passed as an argument to a function. In other words, your function signature is equivalent to :

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

A range-based for loop passes data to the global functions std::begin() and std::end() to get iterators to (respectively) the first and one last element of the container.

Of course, there are no global functions std::begin() and std::end() that take a pointer, and they also cannot be meaningfully defined: how to determine the end of a container specified only by a pointer to its first element?

You can use std::array instead of C arrays ( std::array is a zero-wrapper around the C array) and change your calling function accordingly:

 template <typename T> inline T bigArry(std::array<T, 5> data) // ^^^^^^^^^^^^^^^^ { T level = data[0]; for(T item : data) { if(level<item){ level=item; } } return level; } int main() { std::array<int, 5> data = {1,2,3,4,5}; // ^^^^^^^^^^^^^^^^^^^^^^^ std::cout << bigArry(data); return 0; } 

Here is a living example .

+6
source

Source: https://habr.com/ru/post/948384/


All Articles