【发布时间】:2020-05-22 12:43:12
【问题描述】:
我以这种方式在NS_C 命名空间内创建了一个C 类:
#include <iostream>
namespace NS_C {
template <typename T>
class C {
public:
C operator+(long) {
std::cout << "NS_C::C::operator+\n";
return *this;
}
void not_operator(C<T>, long) {
std::cout << "NS_C::C::not_operator\n";
}
void call() {
*this + 0;
not_operator(*this, 0);
}
};
}
函数call 应该调用NS_C::C::operator+ 然后NS_C::C::not_operator。为了测试这种行为,我运行了这个小程序:
int main()
{
NS_C::C<int> ci;
ci.call();
return 0;
}
输出是我所期望的:
> g++ -o example example.cpp && ./example
NS_C::C::operator+
NS_C::C::not_operator
现在,我想在单独的命名空间 NS_A 中创建一个新类 A,并向该命名空间添加两个通用重载 operator+ 和 not_operator 函数:
#include <iostream>
namespace NS_A {
class A {};
template <typename T>
T operator+(T t, int)
{
std::cout << "NS_A::operator+\n";
return t;
}
template <typename T>
void not_operator(T, int)
{
std::cout << "NS_A::not_operator\n";
}
}
感谢ADL,从NS_C::C<NS_A> 对象调用call 成员函数将调用重载的NS_A::operator+,因为它更好地匹配(第二个参数是NS_A::operator+ 中的int 和long NS_C::C::operator+)。
但是,我不明白为什么我的 not_operator 函数不会发生相同的行为。实际上,NS_C::C::not_operator 仍然会从 call 函数中调用。
让我们使用下面的 main 函数:
int main()
{
NS_C::C<NS_A::A> ca;
ca.call();
return 0;
}
我有以下输出:
NS_A::operator+
NS_C::C::not_operator
为什么在这种情况下不调用NS_A::not_operator?
这里是重现问题的完整代码:
#include <iostream>
namespace NS_A {
class A {};
template <typename T>
T operator+(T t, int)
{
std::cout << "NS_A::operator+\n";
return t;
}
template <typename T>
void not_operator(T, int)
{
std::cout << "NS_A::not_operator\n";
}
}
namespace NS_C {
template <typename T>
class C {
public:
C operator+(long) {
std::cout << "NS_C::C::operator+\n";
return *this;
}
void not_operator(C<T>, long) {
std::cout << "NS_C::C::not_operator\n";
}
void call() {
*this + 0;
not_operator(*this, 0);
}
};
}
int main()
{
NS_C::C<int> ci;
ci.call();
NS_C::C<NS_A::A> ca;
ca.call();
return 0;
}
【问题讨论】:
标签: c++ operator-overloading argument-dependent-lookup