`static const int` 数据成员的 odr 使用成功,但在调用 `const int &` 时没有定义

问题描述

这是一个令人沮丧的问题。我让您猜猜我的构建系统中的哪些代码或条件可能允许以下内容正确构建和运行,而明显的预期是它应该导致链接器未定义引用错误

class Logger
{
public:
  template <typename T>
  Logger & operator<<(const T& r)  // odr-use of static const data member here.
  { return *this;
  }
  //...
};
class SomeClass
{
  static const int a_constant = 42; // used as enum,not defined elsewhere.
  static Logger & logoutput()
  {  static Logger log;
     return log;
  }

  void do_something()
  {  logoutput() 
      << a_constant     //<--- EXPECT undefined reference error here.
      << '\n';          // works fine also.
  }
};

(开发版本为 g++ 9.xx,-std=c++17。CI 构建版本为 g++ 4.6.x。)

在我们的开发环境中,与上述类似的代码构建没有错误,与预期相反。它还过去在我们的 Jenkins CI 环境中没有问题,最近一次是在 3 年前。要问的原因是它现在不再在 CI 中构建,但继续在开发中构建良好。它现在无法在 CI 中构建,这引起了我们的注意。

我的期望是 template<> Logger::operator<<(const int &) 将永远是首选,因为有问题的值是一个 const int。我不希望自由函数能够成为更好的重载匹配。 (这是一个安全的假设吗?)

什么机制可以允许这种白魔法?编译器标志?版本?其他辅助函数签名?

谢谢。

解决方法

您的 CI 使用的是什么版本的 C++?如果它是 C++17(你也应该用适当的版本标记你的问题),你可以像这样声明类成员变量 error[E0658]: associated type bounds are unstable --> /home/fadedbee/test.rs:26:18 | 26 | impl Foo for Bar<T: Foo> { | ^^^^^^ | = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable inline static,它将被声明和定义。>