C++ 我应该使用什么类型的迭代器差分来消除“;可能会丢失数据”;警告?

C++ 我应该使用什么类型的迭代器差分来消除“;可能会丢失数据”;警告?,c++,visual-studio-2010,x86,warnings,64-bit,C++,Visual Studio 2010,X86,Warnings,64 Bit,我需要一个x64模式下警告的通用规则。哪条路更好 考虑下面几行代码 const int N = std::max_element(cont.begin(), cont.end()) - cont.begin(); 或 这是我通常的密码。我对x86没有问题 但如果在x64模式下运行编译器,则会出现一些警告: conversion from 'std::_Array_iterator<_Ty,_Size>::difference_type' to 'int', possible los

我需要一个x64模式下警告的通用规则。哪条路更好

考虑下面几行代码

const int N = std::max_element(cont.begin(), cont.end()) - cont.begin();

这是我通常的密码。我对x86没有问题

但如果在x64模式下运行编译器,则会出现一些警告:

conversion from 'std::_Array_iterator<_Ty,_Size>::difference_type' to 'int', possible loss of data
conversion from '__int64' to 'int', possible loss of data
我认为这不是通用的。还有太多的信

  • 将输出类型替换为
    ptrdiff\u t

    const ptrdiff_t N = std::max_element(cont.begin(), cont.end()) - cont.begin();
    
    那么,我应该如何处理这个未知类型ptrdiff\t? 那么我会收到另外一打警告。 我想用N做很多运算:保存、加法、乘法、循环等等。 重要提示:但是如果
    std::\u数组\u迭代器::差异类型
    ptrdiff\u t
    是不同的类型呢?

  • 将输出类型替换为
    std::_数组_迭代器::差异_类型

    //h-file
    struct S {
        type mymember; // What is the type?
    };
    
    
    //cpp-file
    typedef std::vector<int> cont_t;
    const cont_t::difference_type N = std::max_element(cont.begin(), cont.end()) - cont.begin();
    // Save N
    S mystruct;
    mystruct.mymember = N; // What type of mystruct.mymember?
    
    //h文件
    结构{
    键入mymember;//类型是什么?
    };
    //cpp文件
    typedef标准::矢量控制;
    const cont_t::difference_type N=std::max_元素(cont.begin(),cont.end())-cont.begin();
    //节省
    我的结构;
    mystruct.mymember=N;//什么类型的mystruct.mymember?
    
    我该如何保存N?什么类型的mystruct.mymember?我在h档案里不知道

  • 你的解决方案


  • visual-studio-2010
    中,您可以编写:

    const auto N = std::max_element( cont.begin(), cont.end() ) - cont.begin();
    

    我的解决方案是使用一个已知足够大的类型,基于我拥有的领域知识,但编译器可能无法使用该类型。
    如果编译器随后抱怨数据可能丢失,我会添加一个强制转换(这是保证安全的,因为我事先知道目标类型必须足够大)。

    要保留max_element()的结果,应该使用

    struct Foo { std::vector<int>::difference_type n; };
    
    structfoo{std::vector::difference_type n;};
    

    template struct Foo{std::vector::difference_type n;};
    

    模板结构Foo{tn;};
    
    因为difference_type是difference_type,当您将其转换为int时,会得到未定义的行为

    您可以使用&*c.begin()将迭代器转换为指针,并使用ptrdiff\t表示此指针的差异。

    使用
    std::vector::size\u type

    //h-file
    struct S {
        type mymember; // What is the type?
    };
    
    
    //cpp-file
    typedef std::vector<int> cont_t;
    const cont_t::difference_type N = std::max_element(cont.begin(), cont.end()) - cont.begin();
    // Save N
    S mystruct;
    mystruct.mymember = N; // What type of mystruct.mymember?
    
    • 它保证表示
      差异类型的任何非负值
    • 这是vector的所有索引操作都能接受的
    • 如果
      cont
      为非空,
      std::max_元素(cont.begin(),cont.end())-cont.begin()将不会计算为负值。如果它是空的,那么您无论如何都不应该进行任何处理
    那么我该如何处理这种“未知”类型?那么我会收到另外一打警告。我想用N进行许多运算:保存、加法、乘法、循环等。


    如果您始终使用该类型并将其使用限制在实际需要的地方,则不会收到任何警告
    N
    是向量的索引;这就是它的好处。对它执行的任何有意义的操作都将导致另一个可能的向量索引。

    我将使用
    std::ptrdiff\u t

    我想不出一个合理的实现,
    std::vector::iterator::difference\u type
    不能分配给
    std::ptrdiff\u t
    。他们几乎肯定会是一样的。如果它们不相同,
    差异类型
    必须小于
    ptrdiff\u t

    另外,
    ptrdiff\u t
    是一种有符号类型,因此如果您的所有代码都设计为使用
    int
    s,那么您会比尝试使用无符号类型更好,例如
    std::vector::size\u type

    “如果
    std:\u数组迭代器::difference\u type
    ptrdiff\u t
    是不同的类型呢?”不要使用这样的编译器。而且,在形式上也不可能有什么不同。例如,
    vector
    使用默认的标准分配器就是这种情况,因为这是它获取其typedef的地方,但是由于形式保证不重要(he-he,它真的不重要),我不打算在C++0x草案中查找这一点

    因此,请使用
    ptrdiff\u t

    但是添加一些typedef是个好主意,比如

    typedef ptrdiff_t Size;
    typedef ptrdiff_t Index;
    
    然后在您的具体案例中,您将使用
    索引

    这些typedef自然附带定制的独立式
    countOf
    startOf
    endOf
    函数,使您能够以完全相同的方式处理原始数组和标准库容器

    当您看到名称
    Index
    时,更清楚的一点是,它是一个索引,几乎无论您做什么,都不能很自然地从
    索引
    大小
    类型集中取出。例如,添加一些东西到它,它仍然是一个
    索引
    。因此,大多数情况下,不会有“其他十几个警告”

    但在一些罕见的情况下,你需要从
    索引
    int
    ,比如说。在这些罕见的情况下,只需执行
    静态\u cast
    即可关闭编译器并明确您的意图。甚至是一个自定义的
    静态\u cast
    ——比如
    窄带操作,用于表达


    干杯&hth.,

    什么类型的
    mymember
    <代码>自动
    ?我无法使用
    auto
    @Alexey Malistov保存N:mymember的类型是decltype(mymember)。“强制转换(保证安全)”-这就是“2000年问题”的产生方式。@Kirill:不,使用数据类型(或打印格式)这太小了,无法容纳问题域中所有可能的值,这是2000年问题的根源。我的意思是,您无法确定有多少元素可以容纳容器。您可以估计当前可用平台的限制,但限制会增加。因此,唯一的保证是使用容器的
    差异类型
    关于2000年的问题——在50年代,每个人都认为2个职位就足够代表一年了
    template<typename T> struct Foo { std::vector<T>::difference_type n; };
    
    template<T> struct Foo { T n; };
    
    typedef ptrdiff_t Size;
    typedef ptrdiff_t Index;