1

static_assert以下が成功するのはなぜですか?オペレーターをフレンドにしただけで、<<どこにも作っていません。

struct foo {
  friend std::ostream &operator<<(std::ostream &stream, const foo &f);
};

template<typename T>
struct bar {
  //succeeds:
  static_assert(boost::has_left_shift<std::ostream,T>::value, "failure");
};

int main(int,char**) {
  bar<foo> b;
  return 0;
}
4

1 に答える 1

2

フレンド宣言は、演算子が存在することを確立します。あなたがそれを使用した場合、コンパイラはそれを受け入れます:

std::cout << foo();

アサーションでテストできるのはこれだけです。演算子を定義していないため、このステートメントを含むプログラムはおそらくリンクしませんが、コンパイラと同様に、アサーションはそれを検出できません。他の翻訳単位が最終的にその関数の定義を提供するかどうかはわかりません。

コンパイルとリンクは別のフェーズです。

別のファイルで定義を提供し、そのファイルをコンパイルすると、コンパイルされた 2 つのファイルをリンクして、完全なプログラムを形成できます。最初のファイルを再コンパイルする必要はありません。それが個別のコンパイルのすべてです。

于 2013-06-28T15:43:22.753 に答える