我有一个用于std::chrono::duration的重载的std::chrono::duration。据我所知,我必须把它放在std::chrono名称空间中,这样ADL才能工作。但是,由于某种原因,当我这样做时,所有其他对std::chrono::duration的引用都被VSCode标记为ambiguous。这可能只是一个VSCode错误,但是它使用clangd来进行正确性检查,所以我想知道我的代码是否真的有问题。它是进行编译的,但是VSCode并没有使用与我编译的完全相同的clang,所以也许我的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缺陷?
发布于 2020-01-21 21:53:47
您的代码是非法的,并且有未定义的行为。不允许将自己的函数添加到std命名空间中。您可以添加到它的唯一东西是函数模板专门化(直到C++20)和类模板自己类型的专门化。
一些进一步的建议:对于不属于的类型,您不应该重载操作符。如果该类型的所有者决定自己添加一个,那么您可能/将违反ODR (一个定义规则),并且不需要编译器进行诊断,因此很难找到bug。如果要扩展该功能,请在自己的命名空间中创建自己的命名函数。
https://stackoverflow.com/questions/59849689
复制相似问题