-3
template<typename T>    
void func(T* arr, size_t length)
{
    size_t size_half = length / 2;
    T* left = arr, right = arr + size_half; // Cannot initialize a variable of type 'int' with an rvalue of type 'int *'
}

It seems to me like the compiler thinks right is of type int instead of int*, why?

Francisco Aguilera
  • 3,099
  • 6
  • 31
  • 57

3 Answers3

4

Because the * is attached to the right, and not the left.

Look at it more like:

T  *left,  right

That's just how the language syntax is defined. You can fix it by:

T *left=...,*right=....;
Photon
  • 3,182
  • 1
  • 15
  • 16
  • Well, this also gets into the whole where to place the pointer syntax argument :) The way I used to think about it was int* as being its own type, just as double* and double are types, so i always placed the * on the left. I've been swayed to start placing the pointer to the right now, for situations like this. – Francisco Aguilera Mar 08 '15 at 09:22
  • 1
    @FranciscoAguilera The real solution is to stick to one single declaration per line. Putting the pointer on the right also looks silly. Unfortunately, this crappy syntax is inherited from C. – juanchopanza Mar 08 '15 at 09:23
  • A common solution that avoids ambiguity is to first do something like: `typedef T* pointer;` and then do `pointer left=...,right=...;` – Photon Mar 08 '15 at 09:24
  • @Photon: I don't recommend a `typedef T* pointer;` because it makes code less readable. – Basile Starynkevitch Mar 08 '15 at 09:26
  • @Basile Starynkevitch - I don't know why you would consider it less readable. Even the standard library implementations (both g++ and Visual Studio) use such definitions all over the place. – Photon Mar 08 '15 at 10:16
  • So it seems it's subjective. I find it improves readability. I'm of course referring to the `typedef`, not necessarily to the name `pointer` – Photon Mar 08 '15 at 11:27
2

In types, the * apply to the following , so you should code:

template<typename T> void func(T* arr, size_t length) {
  size_t size_half = length / 2;
  T *left = arr, 
    *right = arr + size_half; 
  //etc...
}

Actually, I think that you should declare one pointer per line:

  T *left= arr;
  T *right= arr + size_half;

or even (C++11 style):

  T *left {arr};
  T *right {arr + size_half};

or

  auto left {arr};
  auto right {arr + size_half};

declaring each pointer on its line is IMHO much more readable.

BTW, you might consider using std::array<T> or std::vector<T>

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Yeah, thanks, unfortunately the person who asked me to write this is backwards as heck and wants me to use c-style arrays :/ – Francisco Aguilera Mar 08 '15 at 09:23
  • well, the whole point in my mind of the comma-delimited initialization was to do one-liners. Unless there is another purpose behind them, I would use them to do one liners, and your second example for 2 liners. – Francisco Aguilera Mar 08 '15 at 09:28
  • I believe that a one line pointer definition should be very short and readable, so I won't code like you want. – Basile Starynkevitch Mar 08 '15 at 09:30
0

It will be like this

T *left = arr, *right = arr + size_half;
Surajeet Bharati
  • 1,363
  • 1
  • 18
  • 36