输入命名空间时,我遇到了模板运算符重载的一些麻烦。考虑添加数组:
// 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+’
为什么从嵌套命名空间调用时找不到重载的运算符?重载的重点(在本例中)将是一个干净的语法。关于如何使其工作的任何想法,或者甚至可能吗?
最佳答案
operator+
的 Complex
可以声明为 friend
函数在 Complex
,不会污染全局命名空间。您的示例应该在以下更改后编译。
struct Complex {
Complex(){};
explicit Complex(const DoubleArray<2>& components);
DoubleArray<2> _components;
friend Complex operator+(const Complex& rhs, const Complex& lhs) { return Complex(); }
};
根据 C++ standard working draft N4140 ,
When two or more different declarations are specified for a single name in the same scope, that name is said to be overloaded.
在你的情况下,两个
operator+
函数在不同的命名空间中声明,因此无法进行重载解析。当编译器找到第一个匹配项时
Complex operator+(const Complex& rhs, const Complex& lhs)
, DoubleArray
不能隐式转换为 Complex
.因此,您得到了 no match for ‘operator+’
错误。
关于c++ - 命名空间中模板运算符的重载解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59810773/