Вызов статической функции-члена типа value_type контейнера C ++ STL - PullRequest
2 голосов
/ 13 октября 2008

Я пытаюсь понять, почему следующее не работает. У меня есть std :: vector, и я хочу вызвать статическую функцию-член, содержащуюся в value_type, например:

std::vector<Vector> v;
unsigned u = v.value_type::Dim();

где Vector фактически является typedef для шаблонного типа:

template <typename T, unsigned U> class SVector; 
typedef SVector<double, 2> Vector; //two-dimensional SVector containing doubles

и статическая функция-член Dim () фактически указывает на размерность U вектора.

Теперь компилятор возвращает сообщение об ошибке:

 error: ‘SVector<double, 2u>’ is not a base of 
 ‘std::vector<SVector<double, 2u>, std::allocator<SVector<double, 2u> > >

что меня озадачивает. Я могу заменить явно оскорбительную строку на

unsigned u = Vector::Dim();

и это работает, но, очевидно, уродливо, поскольку жестко кодирует предположения о типе значения v ... Спасибо!

1 Ответ

15 голосов
/ 13 октября 2008

Вы получаете доступ к типу value_type через экземпляр переменной, а не к типу переменной.

Метод 1 - это работает:

typedef std::vector<Vector> MyVector;
MyVector v;
unsigned u = MyVector::value_type::Dim();

Метод 2 - или это:

std::vector<Vector> v;
unsigned u = std::vector<Vector>::value_type::Dim();

Если вы вводите определение, как в методе 1, вы не вводите жесткие предположения для параметра векторного шаблона и пишете чистый код.


Редактировать: Расширено, чтобы объяснить поведение этой проблемы в соответствии с запросом владельца вопроса:

Оператор разрешения области :: имеет более высокий приоритет , чем любой другой оператор C ++. Это включает в себя доступ участника из объекта . оператора. Таким образом, когда вы пишете что-то вроде:

unsigned u= v.value_type::Dim();

это разрешает следующий код C ++:

unsigned u = v.SVector<double, 2>::Dim();

и, в конечном счете, сначала решается часть SVector<double, 2>::Dim(). Это заставит экземпляр вектора, объявленный через переменную v, иметь шаблонный внутренний класс с именем SVector. А поскольку этого не происходит, это приводит к ошибке:

error C2039: 'SVector<double,2>' : is not a member of 'std::vector<_Ty>'

STL vector необходимо будет "расширять" для каждого использования этого шаблона (доступ к экземпляру переменной через тип_значения, а не к типу переменной). Это не очень хорошее решение, так как оно приводит к большому количеству шаблонов и ненужному и не поддерживаемому коду . Следуя вышеупомянутым решениям, вы избегаете всего этого и можете легко делать то, что хотели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...