c++ - 命名空间中模板运算符的重载解析

标签 c++ namespaces operator-overloading overload-resolution

输入命名空间时,我遇到了模板运算符重载的一些麻烦。考虑添加数组:

// 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/

相关文章:

PHP 的 "use"关键字和自动加载

c++ - 运算符重载和继承

c++ - 可以使用函数指针数组来删除分支吗

c++ - 使用变量索引对 vector 的 vector 进行排序

C++:如何访问相同命名空间中但在不同文件中定义的变量?

c++ - 如何在 C++ 中为枚举重载++ 运算符

c++ operator[] 重载问题(工作正常但不适用于指针,为什么?)

c++ - 为什么opengl不显示我的火焰粒子

c++ - 使用 CMake 2.8.1 为 Visual Studio 2005 添加编译器标志

Java+DOM : How do I convert a DOM tree without namespaces to a namespace-aware DOM tree?