我对operator<<
的两个定义之间的冲突感到不安。
假设我一直是ACE库的忠实粉丝并且在我的代码中使用ACE_Time_Value。有一天,我注意到ACE 6.x已经出局,并试图将我的代码从ACE 5.x迁移到6.x.然后我遇到了一个问题:ACE 6.x在全局命名空间中新引入了operator<<(std::ostream &, const ACE_Time_Value &)
,但是我的代码自5.x时代开始实现了我自己的operator<<
版本,并且两个operator<<
冲突了。不幸的是,“官方”operator<<
的输出不能令人满意,我需要继续使用我自己的版本。我怎么能假装全局命名空间中没有“官方”operator<<
?幸运的是(?)我的所有代码都在我自己的命名空间内。
从概念上讲,我的问题可归纳为:
#include <iostream>
using namespace std;
struct ACE_Time_Value { };
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Apple" ; }
void foo(const ACE_Time_Value &) { cout << "Cherry" << endl; }
namespace mine {
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Banana" ; }
void foo(const ACE_Time_Value &) { cout << "Durian" << endl; }
void bar() {
ACE_Time_Value t;
::mine::foo(t); // OK
// cout << "The current time is " <<
// t << endl; // error: ambiguous overload for 'operator<<'
}
}
int main() {
mine::bar();
}
答案 0 :(得分:1)
您可以执行以下操作并使用继承:
#include <iostream>
using namespace std;
struct ACE_Time_Value { };
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Apple" ; return os; }
void foo(const ACE_Time_Value &) { cout << "Cherry" << endl; }
namespace mine {
struct New_ACE_Time_Value: ACE_Time_Value {};
ostream &operator<<(ostream &os, const New_ACE_Time_Value &) { os << "Banana" ;
return os;
}
void foo(const ACE_Time_Value &) { cout << "Durian" << endl; }
void bar() {
New_ACE_Time_Value t;
::mine::foo(t); // OK
cout << "The current time is " <<
t << endl; // error: ambiguous overload for 'operator<<'
}
}
可能你也应该让'NewACE_Time_Value'不可复制,以摆脱对象切片问题。
答案 1 :(得分:0)
这就是我如何解决你的概念性例子:
#include <iostream>
using namespace std;
struct ACE_Time_Value { };
namespace ACE
{
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Apple" ; return os; }
}
void foo(const ACE_Time_Value &) { cout << "Cherry" << endl; }
namespace mine {
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Banana" ; return os; }
void foo(const ACE_Time_Value &) { cout << "Durian" << endl; }
void bar() {
ACE_Time_Value t;
::mine::foo(t); // OK
cout << "The current time is " << t << endl;
}
}
int main() {
mine::bar();
}
由于ACE是开源的,因此应用相同的修改以使其<<operator
重载包含在命名空间内并不太难。
答案 2 :(得分:0)
首先,您应该添加&#34;返回操作系统;&#34;在我们的运算符重载(&lt;&lt;&lt;)中。 其次,将预处理程序指令添加到两个中的一个&lt;&lt;像这样重载:
#ifdef Oper
ostream &operator<<(ostream &os, const ACE_Time_Value &)
{
os << "Banana" ; return os;
}
#endif
答案 3 :(得分:0)
我最终定义了一个包含operator<<
的包装器对象。
namespace mine {
void foo(const ACE_Time_Value &) { cout << "Durian" << endl; }
struct AceTimePrinter {
const ACE_Time_Value &tv;
AceTimePrinter(const ACE_Time_Value &tv) : tv(tv) { }
inline friend std::ostream &operator<<(
std::ostream &os, const AceTimePrinter &o) {
const ACE_Time_Value &tv = o.tv;
return os << "Durian" ;
}
};
void bar() {
ACE_Time_Value t;
::mine::foo(t); // OK
cout << "The current time is " <<
AceTimePrinter(t) << endl;
}
}
我们选择不使用继承,因为我们无法更改ACE reactor框架中的现有方法签名,例如virtual int handle_timeout (const ACE_Time_Value ¤t_time, const void *act=0)