如何获得vector :: value_type的sizeof?

时间:2021-09-17 01:13:54

I want to get sizeof of the type that is contained in a vector. Here is what I tried:

我想获得向量中包含的类型的sizeof。这是我尝试过的:

#include <iostream>
#include <vector>

int main()
{
    std::vector<uint> vecs;
    std::cout << sizeof(vecs.value_type) << std::endl;
    return 0;
}

From my understanding this should be correct. However, when compiling with GCC 4.8.1 this is what I get:

根据我的理解,这应该是正确的。但是,在使用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;
                           ^

What am I doing wrong? How can I get the size of the contained type?

我究竟做错了什么?如何获得所包含类型的大小?

4 个解决方案

#1


12  

3.4.3 Qualified name lookup [basic.lookup.qual]

3.4.3限定名称查找[basic.lookup.qual]

1 The name of a class or namespace member or enumerator can be referred to after the :: scope resolution operator (5.1) applied to a nested-name-specifier that denotes its class, namespace, or enumeration. If a :: scope resolution operator in a nested-name-specifier is not preceded by a decltype-specifier, lookup of the name preceding that :: considers only namespaces, types, and templates whose specializations are types. If the name found does not designate a namespace or a class, enumeration, or dependent type, the program is ill-formed.

1可以在:: scope resolution运算符(5.1)应用于表示其类,名称空间或枚举的嵌套名称指定符之后引用类或命名空间成员或枚举数的名称。如果嵌套名称指定符中的:: scope resolution运算符之前没有decltype-speci fi er,则查找此前面的名称::仅考虑其专门化为类型的名称空间,类型和模板。如果找到的名称未指定名称空间或类,枚举或依赖类型,则程序格式错误。

In this case, you are accessing a type member from the class template specialization std::vector<uint>, and you need to do it by writing:

在这种情况下,您正在从类模板特化std :: vector 访问类型成员,您需要通过编写以下内容来执行:

std::vector<uint>::value_type

In case you are actually inside templated code and want to e.g. access the same nested type, you need to prefix it with the keyword typename like this:

如果您实际上是在模板化代码中并希望例如访问相同的嵌套类型,您需要使用关键字typename作为前缀,如下所示:

typename std::vector<T>::value_type

In C++11, you can use sizeof(decltype(vecs)::value_type) or also sizeof(decltype(vecs.back())), the latter is convenient if you don't know the precise name of the type but know how to access them through a member function like back().

在C ++ 11中,你可以使用sizeof(decltype(vecs):: value_type)或sizeof(decltype(vecs.back())),如果你不知道类型的确切名称,后者很方便知道如何通过back()等成员函数访问它们。

Note: as pointed out by @Casey in the comments, decltype requires stripping references in order to get the type itself, but for sizeof purposes that doesn't matter.

注意:正如@Casey在评论中指出的那样,decltype需要剥离引用以获取类型本身,但是对于sizeof目的而言无关紧要。

#2


7  

The member access operator . can only be used to access data members and member functions of classes, not other nested names such as type names. You'll need the scope resolution operator :: to access them, and that can only be applied to the class name (or an alias), not an object of class type:

成员访问运算符。只能用于访问类的数据成员和成员函数,而不能用于其他嵌套名称,如类型名称。您需要范围解析运算符::来访问它们,并且只能应用于类名(或别名),而不是类类型的对象:

std::vector<uint>::value_type

In C++11 or later, decltype can give you a type name, if you have an object and no convenient access to the type:

在C ++ 11或更高版本中,如果您有一个对象且无法方便地访问该类型,则decltype可以为您提供类型名称:

decltype(vecs)::value_type

#3


3  

The comments pretty much said it all: if you know the type of the vector, you can use sizeof(std::vector<uint>::value_type). Otherwise use sizeof(decltype(vecs)::value_type).

评论几乎都说了一遍:如果你知道向量的类型,你可以使用sizeof(std :: vector :: value_type)。否则使用sizeof(decltype(vecs):: value_type)。

decltype is a magical C++11 construct that evaluates to the type of its argument, so the code

decltype是一个神奇的C ++ 11结构,它根据其参数的类型进行求值,因此代码也是如此

int i;
float f;

decltype(i) j;
decltype(f) g;

Is the same as

是相同的

int i;
float f;

int j;
float g;

Only use the . operator for fields and methods (technically it can be used for static variable as well, but it's considered bad practice). For anything else, such as static variables, inner classes, or class-scope template parameters or typedefs (such as value_type), use the scope-resolution operator ::.

只使用。字段和方法的运算符(从技术上讲,它也可以用于静态变量,但它被认为是不好的做法)。对于其他任何内容,例如静态变量,内部类或类范围模板参数或typedef(例如value_type),请使用scope-resolution operator ::。

#4


0  

I prefer the more concise:

我更喜欢更简洁:

sizeof(vecs[0])

Which at first glance seems unsafe because what happens when vecs is a zero length vector?

乍一看似乎不安全,因为当vecs是零长度向量时会发生什么?

For this example where the argument to sizeof() operator is called on a value type, the sizeof() operator is executed at compile time and so vecs[0] can never cause a segfault or crash.

对于在值类型上调用sizeof()运算符的参数的示例,sizeof()运算符在编译时执行,因此vecs [0]永远不会导致段错误或崩溃。

p.s. sizeof() is only evaluated at runtime when the argument is a variable-length-array (from C or GNU C++ extension)

附: sizeof()仅在运行时在参数为可变长度数组(来自C或GNU C ++扩展)时计算

#1


12  

3.4.3 Qualified name lookup [basic.lookup.qual]

3.4.3限定名称查找[basic.lookup.qual]

1 The name of a class or namespace member or enumerator can be referred to after the :: scope resolution operator (5.1) applied to a nested-name-specifier that denotes its class, namespace, or enumeration. If a :: scope resolution operator in a nested-name-specifier is not preceded by a decltype-specifier, lookup of the name preceding that :: considers only namespaces, types, and templates whose specializations are types. If the name found does not designate a namespace or a class, enumeration, or dependent type, the program is ill-formed.

1可以在:: scope resolution运算符(5.1)应用于表示其类,名称空间或枚举的嵌套名称指定符之后引用类或命名空间成员或枚举数的名称。如果嵌套名称指定符中的:: scope resolution运算符之前没有decltype-speci fi er,则查找此前面的名称::仅考虑其专门化为类型的名称空间,类型和模板。如果找到的名称未指定名称空间或类,枚举或依赖类型,则程序格式错误。

In this case, you are accessing a type member from the class template specialization std::vector<uint>, and you need to do it by writing:

在这种情况下,您正在从类模板特化std :: vector 访问类型成员,您需要通过编写以下内容来执行:

std::vector<uint>::value_type

In case you are actually inside templated code and want to e.g. access the same nested type, you need to prefix it with the keyword typename like this:

如果您实际上是在模板化代码中并希望例如访问相同的嵌套类型,您需要使用关键字typename作为前缀,如下所示:

typename std::vector<T>::value_type

In C++11, you can use sizeof(decltype(vecs)::value_type) or also sizeof(decltype(vecs.back())), the latter is convenient if you don't know the precise name of the type but know how to access them through a member function like back().

在C ++ 11中,你可以使用sizeof(decltype(vecs):: value_type)或sizeof(decltype(vecs.back())),如果你不知道类型的确切名称,后者很方便知道如何通过back()等成员函数访问它们。

Note: as pointed out by @Casey in the comments, decltype requires stripping references in order to get the type itself, but for sizeof purposes that doesn't matter.

注意:正如@Casey在评论中指出的那样,decltype需要剥离引用以获取类型本身,但是对于sizeof目的而言无关紧要。

#2


7  

The member access operator . can only be used to access data members and member functions of classes, not other nested names such as type names. You'll need the scope resolution operator :: to access them, and that can only be applied to the class name (or an alias), not an object of class type:

成员访问运算符。只能用于访问类的数据成员和成员函数,而不能用于其他嵌套名称,如类型名称。您需要范围解析运算符::来访问它们,并且只能应用于类名(或别名),而不是类类型的对象:

std::vector<uint>::value_type

In C++11 or later, decltype can give you a type name, if you have an object and no convenient access to the type:

在C ++ 11或更高版本中,如果您有一个对象且无法方便地访问该类型,则decltype可以为您提供类型名称:

decltype(vecs)::value_type

#3


3  

The comments pretty much said it all: if you know the type of the vector, you can use sizeof(std::vector<uint>::value_type). Otherwise use sizeof(decltype(vecs)::value_type).

评论几乎都说了一遍:如果你知道向量的类型,你可以使用sizeof(std :: vector :: value_type)。否则使用sizeof(decltype(vecs):: value_type)。

decltype is a magical C++11 construct that evaluates to the type of its argument, so the code

decltype是一个神奇的C ++ 11结构,它根据其参数的类型进行求值,因此代码也是如此

int i;
float f;

decltype(i) j;
decltype(f) g;

Is the same as

是相同的

int i;
float f;

int j;
float g;

Only use the . operator for fields and methods (technically it can be used for static variable as well, but it's considered bad practice). For anything else, such as static variables, inner classes, or class-scope template parameters or typedefs (such as value_type), use the scope-resolution operator ::.

只使用。字段和方法的运算符(从技术上讲,它也可以用于静态变量,但它被认为是不好的做法)。对于其他任何内容,例如静态变量,内部类或类范围模板参数或typedef(例如value_type),请使用scope-resolution operator ::。

#4


0  

I prefer the more concise:

我更喜欢更简洁:

sizeof(vecs[0])

Which at first glance seems unsafe because what happens when vecs is a zero length vector?

乍一看似乎不安全,因为当vecs是零长度向量时会发生什么?

For this example where the argument to sizeof() operator is called on a value type, the sizeof() operator is executed at compile time and so vecs[0] can never cause a segfault or crash.

对于在值类型上调用sizeof()运算符的参数的示例,sizeof()运算符在编译时执行,因此vecs [0]永远不会导致段错误或崩溃。

p.s. sizeof() is only evaluated at runtime when the argument is a variable-length-array (from C or GNU C++ extension)

附: sizeof()仅在运行时在参数为可变长度数组(来自C或GNU C ++扩展)时计算