C ++不能将对中的指针初始化为NULL [英] C++ can't initialize a pointer in a pair to NULL

查看:273
本文介绍了C ++不能将对中的指针初始化为NULL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用g ++ 4.4.7(目前不能更高)编译,并使用 -std = gnu ++ 0x 编译器开关应允许第三行的语法。

  typedef std :: vector< CI_RecordInfo_Pair> CI_RecordInfo_Vector; 
typedef std :: vector< std :: pair< std :: string,CI_RecordInfo_Vector *> > MgrBlks;
MgrBlks mgr_n_blks {{T2M_NAME,NULL}}; // <--- line 59

但是,编译器提示如下:

  /usr/lib/gcc/x86_64-redhat-linux/4.4.7 /../../../../ include /c++.4.4.7/bits/stl_pair.h:在构造符'std :: pair< _T1,_T2> :: pair(_U1&&& _U2&& 9],_U2 = long int,_T1 = std :: basic_string< char,std :: char_traits< char>,std :: allocator< char> >,_T2 = CI_RecordInfo_Vector *]':
tom.cpp:59:从这里实例化
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../ ../../include/c++/4.4.7/bits/stl_pair.h:90:错误:从'long int'到'CI_RecordInfo_Vector *'无效的转换

我假设long int是NULL,并且由于某种原因,我无法将其转换为指针。在结构图中的其他地方,我能够编译像

  foo [X] = {NULL, bar,12}; //第一个元素是指针

有什么区别?

解决方案

编译器拒绝此行是正确的:

  MgrBlks mgr_n_blks {{T2M_NAME,NULL}}; 

在C ++ 11中 std :: pair 具有接受任何参数类型的模板构造函数,然后将它们转换成成员:

  template< typename X,typename Y> 
对(X&& x,Y& y)
:first(std :: forward< X(x)),second(std :: forward&
{}

被定义为 0 0L 或类似的东西,因此模板参数扣除推断构造函数的模板参数为 const char * 和(with GCC) long 。第一个参数类型可以转换为 std :: string ,但 long 不能转换为 CI_RecordInfo_Vector * ,因此无法调用构造函数。



对于结构体映射的其他情况,没有参数推导,赋值必须可转换为struct类型,在这种情况下, NULL 用于直接初始化结构的第一个成员,而不是首先被推导为 long 并初始化 long ,无法转换为指针。



不使用C ++ 11中的 NULL ,发明了 nullptr 以避免这些问题,应该使用它。 / p>

一种可能的解决方法是将参数强制转换为正确的类型:

  MgrBlks mgr_n_blks {{T2M_NAME,(CI_RecordInfo_Vector *)NULL}}; 

但更容易使用 nullptr


I'm compiling with g++ 4.4.7 (and can't go any higher currently), and using the -std=gnu++0x compiler switch, which should allow the syntax of the third line.

typedef std::vector<CI_RecordInfo_Pair>   CI_RecordInfo_Vector;
typedef std::vector<std::pair<std::string, CI_RecordInfo_Vector*> > MgrBlks;
MgrBlks mgr_n_blks { {"T2M_NAME", NULL} };  // <--- line 59

However, the compiler complains as follows:

/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_pair.h: In constructor 'std::pair<_T1, _T2>::pair(_U1&&, _U2&&) [with _U1 = const char (&)[9], _U2 = long int, _T1 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _T2 = CI_RecordInfo_Vector*]':
tom.cpp:59:   instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_pair.h:90: error: invalid conversion from 'long int' to 'CI_RecordInfo_Vector*'

I assume the "long int" is the NULL, and that for some reason I'm unable to convert it to a pointer. Yet elsewhere in a map of structs, I was able to compile something like

foo["X"] = { NULL, "bar", 12 }; // first element is a pointer

What is the difference?

解决方案

The compiler is correct to reject this line:

MgrBlks mgr_n_blks { {"T2M_NAME", NULL} };

In C++11 std::pair has a template constructor that takes any argument types, then converts them to the members:

template<typename X, typename Y>
  pair(X&& x, Y&& y)
  : first(std::forward<X>(x)), second(std::forward<Y>(y))
  { }

NULL must be defined as 0 or 0L or something similar, so template argument deduction deduces the constructor's template arguments as const char* and (with GCC) long. The first argument type is convertible to std::string but long is not convertible to CI_RecordInfo_Vector*, so the constructor cannot be called.

For the other case with a map of structs there is no argument deduction, the RHS of the assignment must be convertible to the struct type, and in that case NULL is used to directly initialize the struct's first member, rather than first being deduced as a long and initializing a long, which cannot be converted to a pointer.

Do not use NULL in C++11, nullptr was invented to avoid exactly these problems, you should use it.

A possible workaround would be to cast the argument to the right type:

MgrBlks mgr_n_blks { {"T2M_NAME", (CI_RecordInfo_Vector*)NULL} };

but it's simpler and clearer just to use nullptr.

这篇关于C ++不能将对中的指针初始化为NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆