Как я могу получить sizeof vector:: value_type?
Я хочу получить sizeof
типа, содержащегося в векторе. Вот что я пробовал:
#include <iostream>
#include <vector>
int main()
{
std::vector<uint> vecs;
std::cout << sizeof(vecs.value_type) << std::endl;
return 0;
}
Из моего понимания это должно быть правильно. Однако при компиляции с GCC 4.8.1 это то, что я получаю:
test-sizeof.cpp: In function ‘int main()’:
test-sizeof.cpp:7:27: error: invalid use of ‘std::vector<unsigned int>::value_type’
std::cout << sizeof(vecs.value_type) << std::endl;
^
Что я делаю неправильно? Как я могу получить размер содержащегося в нем типа?
Ответы
Ответ 1
3.4.3 Квалифицированный поиск имени [basic.lookup.qual]
1 Имя класса или элемента пространства имен или перечислителя может быть упоминаемый после оператора (5.1) разрешения области видимости, примененного к вложенное имя-спецификатор, обозначающее его класс, пространство имен или перечисление. Если оператор разрешения области:: scope вложенному имени-спецификатору не предшествует спецификатор decltype, поиск имя, предшествующее этому:: рассматривает только пространства имен, типы, и шаблоны, специализация которых - типы. Если имя не найдено укажите пространство имен или класс, перечисление или зависимый тип, программа плохо сформирована.
В этом случае вы получаете доступ к члену type
из специализации шаблона класса std::vector<uint>
, и вам нужно сделать это, написав:
std::vector<uint>::value_type
Если вы на самом деле находитесь внутри шаблонного кода и хотите, например, получить доступ к одному и тому же вложенному типу, вам нужно прикрепить его к ключевому слову typename
следующим образом:
typename std::vector<T>::value_type
В С++ 11 вы можете использовать sizeof(decltype(vecs)::value_type)
или также sizeof(decltype(vecs.back()))
, последнее удобно, если вы не знаете точное имя типа, но знаете, как получить к ним доступ через функцию-член, например back()
.
Примечание: как указано в комментариях @Casey, decltype
требует удаления ссылок, чтобы получить сам тип, но для целей sizeof, которые не имеют значения.
Ответ 2
Оператор доступа к члену .
может использоваться только для доступа к элементам данных и функциям членов классов, а не к другим вложенным именам, таким как имена типов. Для доступа к ним вам понадобится оператор разрешения области ::
, и его можно применить только к имени класса (или псевдониму), а не к типу класса:
std::vector<uint>::value_type
В С++ 11 или более поздней версии decltype
может дать вам имя типа, если у вас есть объект и нет удобного доступа к типу:
decltype(vecs)::value_type
Ответ 3
В комментариях в значительной степени сказано все: если вы знаете тип вектора, вы можете использовать sizeof(std::vector<uint>::value_type)
. В противном случае используйте sizeof(decltype(vecs)::value_type)
.
decltype
- это магическая конструкция С++ 11, которая оценивает тип своего аргумента, поэтому код
int i;
float f;
decltype(i) j;
decltype(f) g;
То же, что и
int i;
float f;
int j;
float g;
Используйте только оператор .
для полей и методов (технически он также может использоваться для статической переменной, но он считается плохой практикой). Для чего-либо еще, такого как статические переменные, внутренние классы или параметры шаблона класса или typedefs (например, value_type
), используйте оператор с разрешением области ::
.