柯尼希的查找适用于这里吗?
Does Koenig's lookup apply here?
以下代码段是正确的c++代码吗?
#include <sstream>
class Foo;
std::ostream& operator<<(std::ostream& str, Foo x); // (A)
namespace test {
class Message {
public:
std::ostringstream str;
};
template<typename T>
Message& operator<<(Message& m, T& t)
{
using ::operator<<;
m.str << t;
return m;
}
}
namespace detail {
class Class {
public:
int i;
Class() : i(5) {}
};
}
std::ostream& operator<<(std::ostream& str, detail::Class& myClass) { // (B)
return str << myClass.i;
}
int main() {
test::Message m;
detail::Class c;
m << c;
}
根据http://goo.gl/NkPNau, GCC编译得很好,而Clang没有找到operator<<
(B)。
如果你想知道:这是从一个代码,使用GTest与自定义operator<<
为std::set
打印漂亮的断言消息。我们无法找出一种方法,使它与clang工作,而不是把operator<<
(B)在std命名空间(是的,我知道…)。
Clang是正确的。我们把g++的行为称为语言扩展。
参数依赖查找(又名Koenig查找)确实适用,因为m.str << t
是使用匹配m.str.operator<<(t)
或operator<<(m.str, t)
的最佳重载来解释的,第二种情况是未限定id作为函数名。但是:
14.6.4.2:
对于依赖于模板形参的函数调用,使用通常的查找规则(3.4.1,3.4.2,3.4.3)查找候选函数,除了:
对于使用非限定名查找(3.4.1)或限定名查找(3.4.3)的查找部分,只查找来自模板定义上下文的函数声明。
对于使用关联命名空间查找的部分(3.4.2),只查找在模板定义上下文中或模板实例化上下文中找到的函数声明。
如果函数名是非限定id,并且如果在关联的命名空间内查找考虑所有翻译单元中在这些命名空间中引入的带有外部链接的所有函数声明,而不仅仅考虑在模板定义和模板实例化上下文中找到的那些声明,则调用将是错误的,或者将找到更好的匹配,则程序具有未定义行为。
在模板定义上下文中,(B)不可见。(B)在模板实例化上下文中是可见的,但是全局命名空间不是std::ostringstream
或detail::Class
的关联命名空间。
- FLTK 2.0构建和演示,适用于VS2019的2011年左右的代码库
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 适用于 WebView2 旧版本的示例应用程序
- 在 NVIDIA GEFORCE GTX 1050 上下载适用于 Windows 10 的 openCL 1.2
- __attribute__(优化(0))) 是否适用于"recursively"?
- 为什么 std::erase(std::erase_if) 不是适用于<algorithm>任何容器的模板?
- 使用一个参数的模板函数时出错(适用于 2)
- 使用 适用于 Android 和 iOS 的 tf-lite C++ API
- 为什么这适用于 G++ 而不是 CLANG?
- 适用于 macOS 的 Xcode 应用程序。这就是我设置从USB麦克风输入获取音频的方式。一年前工作,现在没有了。为什么
- 适用于 Linux 的 c++ 上的代理脚本
- 为什么我的 SFINAE 表达式不再适用于 GCC 8.2?
- 使输出流式处理运算符适用于 boost::variant<std::vector<int>、int、double 的正确方法是什么>
- 有没有适用于Windows.lib文件的GNU二进制文件描述符(BFD)
- 模板函数仅适用于VS
- 如何在cmake中包含适用于g++或viceversa的库
- 适用于win32、linux、mac的POSIX C包装器
- WinDBG适用于从Visual Studio 2015保存的转储,但不适用于任务管理器。显示异常代码"not found"
- 从uint8_t到NPY_UINT16 PyArray_SimpleNewFromData.适用于Linux,但不适用于