Подтвердить что ты не робот

Как я могу получить 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;
                           ^

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

4b9b3361

Ответ 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), используйте оператор с разрешением области ::.