【问题标题】:VSCode says std::chrono is ambiguous if operator<< overloadedVSCode 说如果 operator<< 重载,std::chrono 是不明确的
【发布时间】:2020-05-08 00:30:22
【问题描述】:

我有一个重载的operator&lt;&lt; 用于std::chrono::duration。据我了解,我必须将它放在 std::chrono 命名空间中,这样 ADL 才能工作。但是,由于某种原因,当我这样做时,对std::chrono::duration 的所有其他引用都会被 VSCode 标记为ambiguous。这可能只是一个 VSCode 错误,但它使用clangd 进行正确性检查,所以我想知道我的代码是否真的有问题。它确实编译,但 VSCode 没有使用与我正在编译的完全相同的 clang,所以也许我的更宽松?

我能想到的最小例子是:

#include <chrono>
#include <iostream>

// marks chrono as ambiguous
using std::chrono::milliseconds;

namespace std {
namespace chrono {

// again marks chrono as ambiguous
template <class U, class T>
std::ostream& operator<<(std::ostream& os, const typename ::std::chrono::duration<U, T>& dur) {
  os << "foo";
  return os;
}

}  // namespace chrono
}  // namespace std

namespace example {

void DoThing() {
  // NOT marked as ambiguous
  milliseconds x(10);
  // Says no match for operator<< and milliseconds
  std::cout << x;
}

}  // namespace example

在任何人看来,这不是有效的 C++,还是更可能是 clangd 或 VSCode 错误?

【问题讨论】:

  • VSC 是一个编辑器,因此它不能成为编译器错误消息的来源。不要在模板定义中使用class,使用typename

标签: c++ c++11 visual-studio-code


【解决方案1】:

您的代码是非法的并且具有未定义的行为。不允许将自己的函数添加到 std 命名空间中。唯一允许添加的内容是函数模板特化(C++20 之前)和您自己类型的类模板特化。

一些进一步的建议:您不应该为您不拥有的类型重载运算符。如果该类型的所有者决定自己添加一个,那么您可能/将会违反 ODR(一个定义规则),并且不需要编译器进行诊断,因此可能会导致很难找到错误。如果要扩展功能,请在自己的命名空间中创建自己的命名函数。

【讨论】:

  • 所以为namespace std中的现有类型添加operator&lt;&lt;重载是非法的?
  • 正确。不允许向std 添加任何重载。
  • 是的 - 看看那个:en.cppreference.com/w/cpp/language/extending_std。谢谢!
  • @OliverDain 不客气。 Cppreference 从未停止让我对他们在那里的东西感到惊讶。这是我的参考。
猜你喜欢
  • 1970-01-01
  • 2022-12-13
  • 1970-01-01
  • 1970-01-01
  • 2013-04-04
  • 2017-11-25
  • 2019-07-16
  • 2015-05-14
  • 1970-01-01
相关资源
最近更新 更多