输入名称空间时,模板运算符重载时遇到了一些麻烦。考虑添加数组:
// overloads.hpp
#include <array>
namespace mylib {
template <size_t N>
using DoubleArray = std::array<double,N>;
template <size_t N>
DoubleArray<N> operator+( const DoubleArray<N>& lhs, const DoubleArray<N>& rhs ) {return DoubleArray<N>();}
}
在namespace mylib
中进行测试可以达到预期目的。
// test.cpp
#include "overloads.hpp"
namespace mylib {
void test()
{
DoubleArray<3> a({1.0,0.0,0.0});
DoubleArray<3> b({0.0,1.0,0.0});
DoubleArray<3> c(a+b); // <-- ok
}
}
现在假设我在命名空间Complex
中有一个mylib::mysublib
类,它有自己的operator+
和DoubleArray
中的构造函数(此构造函数必须是显式的,以防止隐式转换):
// nested.cpp
#include "overloads.hpp"
namespace mylib {
namespace mysublib {
struct Complex
{
Complex() {};
explicit Complex( const DoubleArray<2>& components );
DoubleArray<2> _components;
};
Complex operator+(const Complex& rhs, const Complex& lhs) {return Complex();}
void testNested()
{
DoubleArray<2> a({1.0,0.0});
DoubleArray<2> b({0.0,1.0});
DoubleArray<2> c(a+b); // <-- no match for ‘operator+’
DoubleArray<2> d( mylib::operator+(a,b) ); // <-- ok
}
}
}
错误消息:
error: no match for ‘operator+’ (operand types are ‘mylib::DoubleArray<2> {aka std::array<double, 2>}’ and ‘mylib::DoubleArray<2> {aka std::array<double, 2>}’)
DoubleArray<2> c(a+b); // <-- no match for ‘operator+’
为什么从嵌套名称空间调用时找不到重载运算符?重载的全部要点(在此示例中)将是一种简洁的语法。关于如何使其正常工作甚至可能的任何想法?
答案 0 :(得分:1)
将您的第三个代码替换为
namespace mylib {
namespace mysublib {
struct Complex
{
Complex() {};
explicit Complex( const DoubleArray<2>& components );
DoubleArray<2> _components;
};
//Complex operator+(const Complex& rhs, const Complex& lhs) {return Complex();}
void testNested()
{
DoubleArray<2> a({1.0,0.0});
DoubleArray<2> b({0.0,1.0});
DoubleArray<2> c(a+b); // <-- no match for ‘operator+’
DoubleArray<2> d( mylib::operator+(a,b) ); // <-- ok
}
}
}
,然后编译。
定义Complex operator+(const Complex& rhs, const Complex& lhs) {return Complex();}
隐藏了意图的运算符
答案 1 :(得分:1)
在X
中可以将operator+
的{{1}}声明为Complex
函数,它不会污染全局名称空间。您的示例应在进行以下更改后编译。
friend
根据C++ standard working draft N4140
在相同范围内为单个名称指定两个或多个不同的声明时,该名称被称为重载。
在您的情况下,两个Complex
函数在不同的名称空间中声明,因此不符合重载解析的条件。
当编译器找到第一个匹配项struct Complex {
Complex(){};
explicit Complex(const DoubleArray<2>& components);
DoubleArray<2> _components;
friend Complex operator+(const Complex& rhs, const Complex& lhs) { return Complex(); }
};
时,operator+
无法隐式转换为Complex operator+(const Complex& rhs, const Complex& lhs)
。因此,您遇到了DoubleArray
错误。