跨命名空间覆盖运算符
Override operator across namespaces
这个问题是关于 C++03 的。
在我的命名空间中,我从不同的命名空间中键入了一个 class,然后尝试为该 class 重载一个运算符。我知道 typedef 只是一个别名而不是一个新类型,因此当 ADL 启动时我的重载没有被使用。起初这对我来说并不直观。我想知道是否有办法 "select" 我的过载,或者以某种方式 "guide" 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;
}
在这里,我使用来自 ::my
的对象调用 other::f()
,即使 obj
实际上是 boost
中的 class 的类型定义。这输出:Boost implementation
。我该怎么做才能让 My implementation
变成 运行?标记为 // ***
的行似乎可以做到这一点,但我宁愿 other::f()
不关心模板参数来自哪些命名空间。
您可以通过在您自己的文件中重载使用相同命名空间的函数来劫持 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;
}
}
这个问题是关于 C++03 的。
在我的命名空间中,我从不同的命名空间中键入了一个 class,然后尝试为该 class 重载一个运算符。我知道 typedef 只是一个别名而不是一个新类型,因此当 ADL 启动时我的重载没有被使用。起初这对我来说并不直观。我想知道是否有办法 "select" 我的过载,或者以某种方式 "guide" 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;
}
在这里,我使用来自 ::my
的对象调用 other::f()
,即使 obj
实际上是 boost
中的 class 的类型定义。这输出:Boost implementation
。我该怎么做才能让 My implementation
变成 运行?标记为 // ***
的行似乎可以做到这一点,但我宁愿 other::f()
不关心模板参数来自哪些命名空间。
您可以通过在您自己的文件中重载使用相同命名空间的函数来劫持 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;
}
}