在测试已声明但未定义的运算符是否存在时,static_assert真的应该成功吗?

Should static_assert really succeed when testing existence of an operator that's declared but not defined?

本文关键字:真的 assert static 成功 声明 测试 未定义 存在 是否 运算符      更新时间:2023-10-16

为什么下面的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;
}

友元声明确定运算符存在。如果你使用它,编译器会接受它:

std::cout << foo();

这就是断言所能测试的全部内容。包含此语句的程序可能不会链接,因为您没有定义运算符,但就像编译器一样,断言无法检测到这一点。它不知道其他翻译单元是否最终会为该功能提供定义。

编译和链接是分开的阶段。

如果您在另一个文件中提供了定义,并编译了该文件,则可以将两个编译后的文件链接在一起,形成一个完整的程序。您不必重新编译第一个文件。这就是单独编译的全部内容。