Наследование от std::vector, ошибка компилятора? (самый неприятный разбор)

Для тех, кто видит этот вопрос: взгляните на ответ и рассмотрите возможность использования: cdecl

Почему приведенный ниже код выдает ошибку компилятора:

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();
    ^

Я не понимаю, что не так с этим кодом?

#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??
}

person Gabriel    schedule 25.06.2014    source источник
comment
Самый неприятный разбор, a - это функция.   -  person Csq    schedule 25.06.2014
comment
почему это функция?   -  person Gabriel    schedule 25.06.2014
comment
@Gabriel, прочитайте о MVP, и вы поймете, почему.   -  person chris    schedule 25.06.2014
comment
Это ближайшая запись часто задаваемых вопросов: stackoverflow.com/questions/ 180172/   -  person Csq    schedule 25.06.2014


Ответы (1)


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

Это объявление функции a, которая возвращает RangeVec<int> и принимает один аргумент с именем b типа RangeVec<int>. Это самый неприятный анализ. Вы можете исправить это с помощью единого синтаксиса инициализации С++ 11:

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

Или, если у вас нет компилятора C++11, просто введите дополнительную пару скобок:

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

Также обратите внимание, что наследование от стандартных контейнеров обычно плохая идея.

person Joseph Mansfield    schedule 25.06.2014
comment
Мне кажется, что объявление функции выглядит следующим образом, а не так, как указано выше? ------------------------------------------------------------- RangeVec<int> (a)( RangeVec<int> ) - person Gabriel; 25.06.2014
comment
@Gabriel Это эквивалентное объявление (только без имени параметра). - person Joseph Mansfield; 25.06.2014
comment
Но как RangeVec<int>(b) может быть параметром? Я бы согласился, что RangeVec<int> b это параметр, но со скобками?? я не понимаю - person Gabriel; 25.06.2014
comment
@Gabriel Точно так же int(x); является допустимым объявлением переменной с именем x типа int. Как и int(((((((x)))))));. Вы можете иметь произвольные круглые скобки вокруг идентификатора объявления. - person Joseph Mansfield; 25.06.2014
comment
не является int(x) конструктором для объекта типа int, который создает временный объект без имени в области видимости - person Gabriel; 25.06.2014
comment
@Gabriel Вы думаете об этом, когда это выражение (в этом случае это функциональная нотация приведения). Здесь это не выражение, это объявление. - person Joseph Mansfield; 25.06.2014
comment
Очень хороший сайт, чтобы проверить, что означает декларация! cdecl.ridiculousfish.com/?q=int+a% 28int%28%29%29 - person Gabriel; 27.06.2014