4

For people who see this question: Take a look at the answer and consider using: cdecl

Why does the code below give a compiler error:

prog.cpp: In function ‘int main()’:
prog.cpp:23:4: error: request for member ‘size’ in ‘a’, which is of non-class type ‘RangeVec<int>(RangeVec<int>)’
  a.size();
    ^

I don't understand what's wrong with this code?

#include <iostream>
#include <vector>

template<typename Type>
class RangeVec: public std::vector<Type> {
    public:

        RangeVec( const RangeVec & v): std::vector<Type>(v){}
        RangeVec( const RangeVec && v): std::vector<Type>(std::move(v)) {}

        RangeVec( const std::vector<Type> &v)
            : std::vector<Type>(v)
        {
            //std::sort(std::vector<Type>::begin(),std::vector<Type>::end());
        }
};

int main(){
    std::vector<int> v;
    RangeVec<int> b(v);
    RangeVec<int> a(  RangeVec<int>(b) );
    a.size(); // b.size() works ???? why??
}
SU3
  • 5,064
  • 3
  • 35
  • 66
Gabriel
  • 8,990
  • 6
  • 57
  • 101

1 Answers1

5
 RangeVec<int> a(  RangeVec<int>(b) );

This is a declaration of a function a that returns a RangeVec<int> and takes one argument called b of type RangeVec<int>. This is the most vexing parse. You can fix it with C++11's uniform initialization syntax:

 RangeVec<int> a{RangeVec<int>{b}};

Or if you don't have a C++11 compiler, just introduce an extra pair of parantheses:

 RangeVec<int> a((RangeVec<int>(b)))

Note also that deriving from standard containers is usually a bad idea.

Community
  • 1
  • 1
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • I though a function declaration looks as follows and not as the above? ---------------------------------------------- `RangeVec (a)( RangeVec )` – Gabriel Jun 25 '14 at 19:01
  • 1
    @Gabriel That's an equivalent declaration (just without the parameter name). – Joseph Mansfield Jun 25 '14 at 19:04
  • But how can `RangeVec(b)` be a parameter? I would aggree that `RangeVec b` is a parameter but with the brackets?? I dont get it – Gabriel Jun 25 '14 at 19:06
  • @Gabriel The same way `int(x);` is a valid declaration of a variable called `x` of type `int`. So is `int(((((((x)))))));`. You can have arbitrary parentheses around the declaration identifier. – Joseph Mansfield Jun 25 '14 at 19:08
  • isnt `int(x)` a constructor for an object of type `int` which produces a temporary with no name in the scope – Gabriel Jun 25 '14 at 19:10
  • 3
    @Gabriel You're thinking about it when it's an expression (in which case it's the function-like cast notation). Here's it's not an expression, it's a declaration. – Joseph Mansfield Jun 25 '14 at 19:12
  • A verygood site is the following to check what the declaration means! http://cdecl.ridiculousfish.com/?q=int+a%28int%28%29%29 – Gabriel Jun 27 '14 at 08:38