Я пытаюсь понять, почему следующее не работает. У меня есть 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();
и это работает, но, очевидно, некрасиво, поскольку оно жестко закодирует предположения о value_type v ... Спасибо!





Вы получаете доступ к значению_типа через экземпляр переменной, а не к типу переменной.
Способ 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();
Если вы набираетеdef, как в методе 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 должен быть «расширен» для каждого использования этого шаблона (доступ value_type через экземпляр переменной, а не тип переменной). Это не лучшее решение, так как приводит к множеству шаблонов и ненужный и неподдерживаемый код. Следуя вышеупомянутым решениям, вы избегаете всего этого и легко можете делать то, что хотели.
@yungchin проверьте, достаточно ли ясно объяснение, которое я только что добавил, об этой проблеме.
ничего не пошло бы не так, если бы это было разрешено - поскольку C++ статически типизирован, он уже знает, что v является std :: vector <Vector>, но опять же ВЫ уже знаете, что такое v, так что на самом деле это не имеет никакого значения. Я предполагаю, что разработчики C++ хотели четкого разделения между статическими членами и членами экземпляра.
@Greg and smink: круто, спасибо. Теперь мне это совершенно ясно.
Большое спасибо, это здорово. Я не знал, что ему нельзя получить доступ к значению_типа через экземпляр. Не могли бы вы случайно узнать, почему это запрещено (что бы пошло не так, если бы это было разрешено)?