7

私はg ++ 4.4.7でコンパイルしており(現在はそれ以上に進むことはできません)、-std=gnu++0x3行目の構文を許可するコンパイラスイッチを使用しています。

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: 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*'

「long int」はNULLであり、何らかの理由でそれをポインターに変換できないと思います。しかし、構造体のマップの他の場所では、次のようなものをコンパイルできました

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

違いはなんですか?

4

1 に答える 1

15

コンパイラはこの行を拒否するのが正しいです:

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

C++11std::pairには、引数の型を取り、それらをメンバーに変換するテンプレート コンストラクターがあります。

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

NULL0orまたは類似のものとして定義する必要がある0Lため、テンプレート引数推定は、コンストラクターのテンプレート引数をconst char*and (GCC を使用)として推定しlongます。最初の引数の型は に変換できますstd::stringが、longに変換CI_RecordInfo_Vector*できないため、コンストラクターを呼び出すことはできません。

構造体のマップを使用する他のケースでは、引数推定はありません。代入の RHS は構造体型に変換可能でなければならず、その場合、最初にandNULLとして推定されるのではなく、構造体の最初のメンバーを直接初期化するために使用されます。ポインタに変換できない をlong初期化しています。long

NULLC++11 では使用しないでくださいnullptr。これらの問題を正確に回避するために考案されたものです。使用する必要があります。

考えられる回避策は、引数を正しい型にキャストすることです。

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

を使用するだけで、よりシンプルで明確になりますnullptr

于 2013-08-13T19:19:56.967 に答える