首页 文章

如何获得vector :: value_type的sizeof?

提问于
浏览
19

我想得到一个包含在向量中的 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;
                           ^

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

4 回答

  • 13

    评论几乎都说了一遍:如果你知道向量的类型,你可以使用 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;
    

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

  • 3

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

    std::vector<uint>::value_type
    

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

    decltype(vecs)::value_type
    
  • 8

    3.4.3 Qualified name lookup [basic.lookup.qual]

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

    在这种情况下,您正在从类模板特化 std::vector<uint> 访问 type 成员,您需要通过编写:

    std::vector<uint>::value_type
    

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

    typename std::vector<T>::value_type
    

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

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

  • 1

    我更喜欢更简洁:

    sizeof(vecs[0])
    

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

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

    附:仅当参数是可变长度数组(来自C或GNU C扩展)时,才会在运行时计算 sizeof()

相关问题