错误:从 long int 转换为非标量类型 __gnu_cxx::__normal_iterator
Posted
技术标签:
【中文标题】错误:从 long int 转换为非标量类型 __gnu_cxx::__normal_iterator【英文标题】:error: conversion from long int to non-scalar type __gnu_cxx::__normal_iterator 【发布时间】:2012-06-22 10:14:31 【问题描述】:我正在尝试在 Linux (Redhat) 中运行旧的 C++ 代码。我正在使用 gcc 版本 4.1.2。 这是我遇到错误的代码示例:
template <class TP> TP *GCVVector<TP>::Find(const TP &Obj)
#ifdef WIN32
using namespace std;
typedef typename vector<TP>::iterator Viterator;
#else
#ifdef __HP_aCC
using namespace std;
typedef typename vector<TP>::iterator Viterator;
#else
using namespace std;
typedef typename std::vector<TP>::iterator Viterator;
#endif
#endif
Viterator pCurrent =NULL ;
我得到的错误是这样的:
/trnuser1/rmtrain/DevelopmentEnv/Generic/CoreObjects/GCVVector.h: In member function âTP* GCVVector<TP>::Find(const TP&) [with TP = GCVAsso<GCVString, GCVString>::KeyNode]â:
/trnuser1/rmtrain/DevelopmentEnv/Generic/CoreObjects/GCVAsso.h:165: instantiated from âbool GCVAsso<KTP, VTP>::Add(KTP, VTP) [with KTP = GCVString, VTP = GCVString]â
/trnuser1/rmtrain/DevelopmentEnv/Generic/CoreObjects/GCVTransformationServices.h:69: instantiated from here
/trnuser1/rmtrain/DevelopmentEnv/Generic/CoreObjects/GCVVector.h:398: error: conversion from âlong intâ to non-scalar type â__gnu_cxx::__normal_iterator<GCVAsso<GCVString, GCVString>::KeyNode*, std::vector<GCVAsso<GCVString, GCVString>::KeyNode, std::allocator<GCVAsso<GCVString, GCVString>::KeyNode> > >â requested
/trnuser1/rmtrain/DevelopmentEnv/Generic/CoreObjects/GCVAsso.h:165: instantiated from âbool GCVAsso<KTP, VTP>::Add(KTP, VTP) [with KTP = GCVString, VTP = GCVString]â
/trnuser1/rmtrain/DevelopmentEnv/Generic/CoreObjects/GCVTransformationServices.h:69: instantiated from here
/trnuser1/rmtrain/DevelopmentEnv/Generic/CoreObjects/GCVVector.h:403: error: no match for âoperator=â in âpCurrent = GCVVector<TP>::BinarySearch [with TP = GCVAsso<GCVString, GCVString>::KeyNode](0l, (GCVVector<TP>::GetSize [with TP = GCVAsso<GCVString, GCVString>::KeyNode]() - 1l), ((const GCVAsso<GCVString, GCVString>::KeyNode&)((const GCVAsso<GCVString, GCVString>::KeyNode*)Obj)))â
/usr/lib/gcc/x86_64-redhat- linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_iterator.h:634: note: candidates are: __gnu_cxx::__normal_iterator<GCVAsso<GCVString, GCVString>::KeyNode*, std::vector<GCVAsso<GCVString, GCVString>::KeyNode, std::allocator<GCVAsso<GCVString, GCVString>::KeyNode> > >& __gnu_cxx::__normal_iterator<GCVAsso<GCVString, GCVString>::KeyNode*, std::vector<GCVAsso<GCVString, GCVString>::KeyNode, std::allocator<GCVAsso<GCVString, GCVString>::KeyNode> > >::operator=(const __gnu_cxx::__normal_iterator<GCVAsso<GCVString, GCVString>::KeyNode*, std::vector<GCVAsso<GCVString, GCVString>::KeyNode, std::allocator<GCVAsso<GCVString, GCVString>::KeyNode> > >&)
make[2]: *** [CMakeFiles/GCVCore.dir/trnuser1/rmtrain/DevelopmentEnv/Generic/CoreObjects/GCVTransformationServices.o] Error 1
make[1]: *** [CMakeFiles/GCVCore.dir/all] Error 2
【问题讨论】:
【参考方案1】:原始代码是针对 STL 编写的,其中 std::vector<T>::iterator
是一个原始指针,因此可以(并且需要)初始化为 NULL。
为了完全兼容,将行改为
Viterator pCurrent = Viterator();
在 C++11 中,可以使用
Viterator pCurrent;
完全兼容意味着Viterator
可能只是一个裸指针。在这种情况下,将其显式设置为默认构造值会将其设置为 NULL。下面是一个简单的例子来演示它。
#include <iostream>
typedef void * Iterator;
int main(int, char**)
Iterator v1, v2=Iterator();
std::cout << "uninitialized pointer: " << v1 << "\ninitialized pointer: " << v2 << std::endl;
输出是:
uninitialized pointer: 0x7fff5fc01052
initialized pointer: 0
请注意,如果程序对pCurrent
做了任何事情,除了给它分配一个新值之外,它可能仍然是不正确的(将它与自身进行比较是有效的,或者通过复制它来初始化另一个迭代器,但与一个非奇异迭代器,或单独的默认值构造的迭代器将是未定义的)。
【讨论】:
@Kuba:如果迭代器类型确实是一个指针,那只会让它未初始化。在 C++11 中,您可以使用Viterator pCurrent;
,但在 C++03 中则不行。
Xeo:你是对的!谢谢你把它捡起来。坦率地说,我从来不需要像这样默认构造简单类型,所以我从来没有尝试过。
@Xeo:这只是表明这是一个令人难以置信的网站。我整个月都在学习。再次感谢,当有人指出我不知道的事情时,我总是感激不尽。给我更多的力量;)
iterator() == iterator()
无法保证。如果旧程序依赖空迭代器(而不是礼貌地避免未初始化的迭代器),可能仍然存在问题。
@aschepler: 原来的代码已经在通过检查编译目标来解决编译器的缺点了……【参考方案2】:
迭代器不是一个数字,它是一个大多数时候不将数字作为构造函数参数的对象。
只需将行替换为
Viterator pCurrent = Viterator();
它将以与当前代码相同的方式出现错误。
【讨论】:
如果它是指针或 POD 结构,这可能会使迭代器未初始化。 @Xeo 你说你需要一个
来正确初始化它。即使对于结构,()
在 C++03 中也不够用吗?还是 C++11 中首次引入的初始化保证?
Type name();
在 C++ 中也称为most vexing parse,这实际上声明了一个函数。 ;)以上是关于错误:从 long int 转换为非标量类型 __gnu_cxx::__normal_iterator的主要内容,如果未能解决你的问题,请参考以下文章
从'boost::filesystem3::path'到非标量类型'std::string'的提升错误转换
错误:在 C++ 中从“Counter”转换为非标量类型“CountDn”
在 c语言中int long unsigned 和 char这四种类型数据的转换规律是_____.