Как я могу получить размер вектора :: значение_типа?

я хочу получить 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) << станд :: епсИ;
^

Что я делаю неправильно? Как я могу получить размер содержимого типа?

19

Решение

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 требует извлечения ссылок для получения самого типа, но для целей размера это не имеет значения.

13

Другие решения

Оператор членского доступа . может использоваться только для доступа к элементам данных и функциям-членам классов, но не к другим вложенным именам, таким как имена типов. Вам понадобится оператор разрешения области :: для доступа к ним, и это может быть применено только к имени класса (или псевдониму), а не к объекту типа класса:

std::vector<uint>::value_type

В C ++ 11 или новее decltype может дать вам имя типа, если у вас есть объект и нет удобного доступа к типу:

decltype(vecs)::value_type
8

В комментариях все сказано: если вы знаете тип вектора, вы можете использовать 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), используйте оператор разрешения области ::,

3

Я предпочитаю более сжатые:

sizeof(vecs[0])

Что на первый взгляд кажется небезопасным, потому что происходит, когда vecs такое вектор нулевой длины?

Для этого примера, где аргумент sizeof() Оператор вызывается для типа значения, sizeof() оператор выполняется во время компиляции и так vecs[0] никогда не может вызвать segfault или аварии.

постскриптум sizeof() оценивается только во время выполнения, когда аргумент является массивом переменной длины (из расширения C или GNU C ++)

1
По вопросам рекламы [email protected]