【发布时间】:2020-06-24 13:26:58
【问题描述】:
我尝试在命名空间中重载operator<<。此外,我想在第一个命名空间中包含一个调试命名空间,operator<< 的作用更多。
在 main 函数中,我在第一个命名空间中创建一个类的对象,并使用 std::cout 将其分发出去。我希望必须先“命名”操作员,然后才能这样做,例如 using test::operator<<,但我不必这样做。
这导致了我的问题: 如果我现在想使用我的调试运算符,它是模棱两可的,我不能使用它,我真的不明白为什么。
#include <iostream>
#include <string>
namespace test{
class A{
std::string str_;
public:
explicit A(const std::string& str) : str_{str} {}
inline std::ostream& toStream(std::ostream& os) const {
return os << str_ << "\n";
}
};
std::ostream& operator<< (std::ostream& os, const A& a) {
return a.toStream(os);
}
}
namespace test {
namespace debug {
std::ostream& operator<< (std::ostream& os, const A& a) {
std::string info = "\n\tDebug\n"
"\t\tLine: " + std::to_string(__LINE__) + "\n"
"\t\tFile: " __FILE__ "\n"
"\t\tDate: " __DATE__ "\n"
"\t\tTime: " __TIME__ "\n"
"\t\tVersion: " + std::to_string(__cplusplus) + "\n";
return a.toStream(os) << info;
}
}
}
int main(int argc, const char* argv[]) {
test::A a{"Test"};
if(argc > 1) {
using test::debug::operator<<;
// Ambiguous error
std::cout << a << "\n";
} else {
// Don't need it for some reason
// using test::operator<<;
std::cout << a << "\n";
}
}
【问题讨论】:
-
你能详细说明为什么你认为它没有模棱两可吗?它们具有完全相同的签名。
-
我以为我必须明确使用
using test::operator<<;告诉编译器在哪里找到重载,因为它隐藏在命名空间“test”中。 -
额外的调试数据不会给你太多。
__FILE__和__LINE__将始终是定义operator<<的文件。我假设您想获取您调用的行和文件? -
哦,我不知道。是,对的。我认为预处理器使用了调用它的文件和行。
-
不,很遗憾没有。这就是日志库通常使用宏的原因,例如:#define LOG(msg) std::cout FILE LINE
标签: c++ namespaces operator-overloading c++17 overloading