C++ can't initialize a pointer in a pair to NULL

痞子三分冷 提交于 2019-12-10 13:09:59

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/18217221/c-cant-initialize-a-pointer-in-a-pair-to-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!