C++ 我应该使用什么类型的迭代器差分来消除“;可能会丢失数据”;警告?
我需要一个x64模式下警告的通用规则。哪条路更好 考虑下面几行代码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
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
是向量的索引;这就是它的好处。对它执行的任何有意义的操作都将导致另一个可能的向量索引。我将使用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;