9

このことを考慮:

std::vector<int*> v(1, 0);

これはVC++10で正常にコンパイルされます(最大警告レベルでも警告はありません)。ただし、macの場合はllvm、Linuxの場合はgccでコンパイルされないため、「互換性のない型constintからint*に割り当てます」などのエラーが発生します。私は解決策を探していません-2番目のパラメーターが不要であるか、static_castがエラーを修正することを知っています。

ゼロは暗黙的に任意のポインタ型に変換できると思いました。何が得られますか?私は次のことができます:

int* i = 0;
int* const& ii = 0;
const int t = 0;
i = t;

const T&ベクトルコンストラクターの署名は、展開すると正しくvector<int*>なるものを取ることを理解していint* const&ますか?誰かがここで何が起こっているのか、そしてVC++または非VC++コンパイラが正しいかどうかを説明できますか?

4

2 に答える 2

2

ここでは実際に g++ が間違っているようです。C++98 23.1.1/9 を参照してください:

この節と節 21 で定義されたすべてのシーケンスについて:

— コンストラクター テンプレート X(InputIterator f, InputIterator l, const Allocator& a = Allocator())

X(static_cast<typename X::size_type>(f), static_cast<typename X::value_type>(l), a)InputIterator が整数型の場合と同じ効果があります。

これはコンストラクターへのテンプレート パラメーターであることに注意してくださいInputIterator。この場合、これはint例のためのものであり、したがって整数型です。g++ ライブラリには、実際には、格納されている型vectorが整数であるすべてのケースを処理するための特定のコードがあり、それらはすべて適切に機能します。この場合、使用0したという理由だけstatic_castで、標準によって指示されたものが実際に合法になります。標準が同等であると述べているコードをコンパイルしてみましたが、g++ 4.5 でコンパイルされます。

于 2012-04-04T20:12:35.393 に答える
2

std::vectorこの署名を持つ厄介なコンストラクターがあります

template <class InputIterator>
vector(InputIterator first, InputIterator last,
       const Allocator& = Allocator());

これは、コンパイラがパラメータとから (!)InputIteratorとして差し引く場合、適切に適合しますが、私たちが望むことはしません。int01

C++11 では、パラメーターが実際にイテレーターであるかどうかを判断するために、コンパイラーがさらに努力する必要があると思います。C++03 では、おそらくsize_type(1)andint(0)になり、問題が発生します。

整数リテラル 0 は NULL ポインタに変換できますが、int値 0​​ を持つものは変換できません!

于 2012-04-04T19:14:08.850 に答える