я хочу получить 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: в функции int main (): test-sizeof.cpp: 7: 27: ошибка: неверное использование ‘std :: vector<без знака int>::тип ценности' станд :: соиЬ << SizeOf (vecs.value_type) << станд :: епсИ; ^
Что я делаю неправильно? Как я могу получить размер содержимого типа?
3.4.3 Поиск по квалифицированному имени [basic.lookup.qual]
1 Имя члена класса, пространства имен или перечислителя может быть
упоминается после того, как оператор разрешения области видимости (5.1) применяется к
nested-name-specier, который обозначает его класс, пространство имен или
перечисление. Если оператор разрешения :: области видимости в
nested-name-specier не предшествует decltype-specier, поиск
имя, предшествующее этому :: рассматривает только пространства имен, типы, а также
шаблоны, специализация которых является типами. Если имя не найдено
обозначить пространство имен или класс, перечисление или зависимый тип,
Программа плохо сформирована.
В этом случае вы получаете доступ к type
член от специализации шаблона класса std::vector<uint>
и вам нужно сделать это, написав:
std::vector<uint>::value_type
Если вы на самом деле внутри шаблонного кода и хотите, например, доступ к тому же вложенному типу, вам нужно поставить префикс с ключевым словом typename
как это:
typename std::vector<T>::value_type
В C ++ 11 вы можете использовать sizeof(decltype(vecs)::value_type)
или также sizeof(decltype(vecs.back()))
последнее удобно, если вы не знаете точного имени типа, но знаете, как получить к ним доступ через функцию-член, например back()
,
Заметка: как указано @Casey в комментариях, decltype
требует извлечения ссылок для получения самого типа, но для целей размера это не имеет значения.
Оператор членского доступа .
может использоваться только для доступа к элементам данных и функциям-членам классов, но не к другим вложенным именам, таким как имена типов. Вам понадобится оператор разрешения области ::
для доступа к ним, и это может быть применено только к имени класса (или псевдониму), а не к объекту типа класса:
std::vector<uint>::value_type
В C ++ 11 или новее decltype
может дать вам имя типа, если у вас есть объект и нет удобного доступа к типу:
decltype(vecs)::value_type
В комментариях все сказано: если вы знаете тип вектора, вы можете использовать sizeof(std::vector<uint>::value_type)
, В противном случае используйте sizeof(decltype(vecs)::value_type)
,
decltype
является магической конструкцией C ++ 11, которая оценивает тип своего аргумента, поэтому код
int i;
float f;
decltype(i) j;
decltype(f) g;
Такой же как
int i;
float f;
int j;
float g;
Используйте только .
оператор для полей и методов (технически его можно использовать и для статических переменных, но это считается плохой практикой). Для чего-либо еще, такого как статические переменные, внутренние классы, или параметры шаблона области действия класса или определения типа (такие как value_type
), используйте оператор разрешения области ::
,
Я предпочитаю более сжатые:
sizeof(vecs[0])
Что на первый взгляд кажется небезопасным, потому что происходит, когда vecs
такое вектор нулевой длины?
Для этого примера, где аргумент sizeof()
Оператор вызывается для типа значения, sizeof()
оператор выполняется во время компиляции и так vecs[0]
никогда не может вызвать segfault или аварии.
постскриптум sizeof()
оценивается только во время выполнения, когда аргумент является массивом переменной длины (из расширения C или GNU C ++)