这个问题与C ++ 03有关。
在我的命名空间中,我从不同的命名空间中键入一个类,然后尝试重载该类的运算符。我知道typedef只是一个别名而不是一个新类型,因此当我的重载中的ADL踢不使用时。起初这对我来说并不直观。我想知道是否有办法“选择”我的重载,或以某种方式“引导”ADL到正确的命名空间?
以下是一个简化的案例:
#include <iostream>
namespace boost
{
template<typename T>
struct some_type{};
template<typename T, typename U>
T& operator<<(T& os, some_type<U> const& obj)
{
os << "Boost implementation";
return os;
}
}
namespace my
{
typedef boost::some_type<int> typedefed_type;
template<typename T>
T& operator<<(T& os, typedefed_type const& obj)
{
os << "My implementation";
return os;
}
}
namespace other
{
template<typename T>
void f(T const& obj)
{
// using namespace my; // ***
std::cout << obj << std::endl;
}
}
int main(int argc, char* argv[])
{
my::typedefed_type obj;
other::f(obj);
return 0;
}
在这里,我使用other::f()
中的对象调用::my
,即使obj
实际上是boost
中类的typedef。这输出:Boost implementation
。如何让My implementation
运行?标记为// ***
的行似乎是这样做的,但我宁愿不让other::f()
关心模板参数来自哪些名称空间。
答案 0 :(得分:1)
您可以通过在您自己的文件中重载使用相同命名空间的函数来劫持boost
命名空间中的泛型实现。
继续在my
命名空间中拥有自己的通用实现,然后添加:
namespace boost
{
typedef some_type<int> typedefed_type;
template<typename T>
T& operator<<(T& os, typedefed_type const& obj)
{
return my::operator<<(os, obj);
}
}
然后,您在<<
命名空间中使用other
运算符非常简单。
namespace other
{
template<typename T>
void f(T const& obj)
{
std::cout << obj << std::endl;
}
}