Operator overload not found when used in lambda in namespace

The following does not compile (with Clang 5.0.0 / gcc 7.3, std: C ++ 11):

Error message in Clang:

error: invalid operands to binary expressions ( std::vector<double, std::allocator<double> >and std::vector<double, std::allocator<double>>)

#include <functional>
#include <vector>

namespace ns{

using MyType = std::vector<double>;

} // namespace ns

using ns::MyType;
MyType& operator+=( MyType& lhs, const MyType& rhs) {
  for (int i = 0; i < lhs.size(); ++i) {
    lhs[i] = lhs[i] + rhs[i];
  }
  return lhs;
}
MyType operator+( MyType lhs, const MyType& rhs) {
  lhs += rhs;
  return lhs;
}

namespace ns{

using Func = std::function<MyType()>;

Func operator+(
    const Func &lhs, const Func &rhs) {
  return [lhs, rhs]() {
    auto y = lhs() + rhs(); // <-- error in this line
    return y;
  };
}

} // namespace ns

The compiler does not find the correct overload operator+. I do not understand why. The reason I define operators outside of the namespace is because ADL does not work for typedefs and uses type aliases . What is the problem? Why can't the compiler find operator+(MyType, const MyType &)in the above circumstances?

All of the following options are compiled:

namespace ns {

MyType a, b;
auto c = a + b; // compiles

MyType f() {
    MyType a_, b_;
    return a_ + b_; // compiles
};

Func operator+(
    const Func &lhs, const Func &rhs) {
  return [lhs, rhs]() {
    auto x = lhs();
    x += rhs(); // <-- compiles; operator+= instead of operator+
    return x;
  };
}

} // namespace ns

Func operator+(
    const Func &lhs, const Func &rhs) {
  return [lhs, rhs]() {
    auto y = lhs() + rhs(); // <-- no error if not in namespace ns
    return y;
  };
}
+4
source share
2 answers

operator+, operator+ . , . , operator+, , . . . .

, :: , , , - , , .

, . , .

:: operator ++

namespace ns {
    using Func = std::function<MyType()>;
    using ::operator+;

    Func operator+(
        const Func &lhs, const Func &rhs) {
        return [lhs, rhs]() {
            auto y = lhs() + rhs();
            return y;
        };
    }

} // namespace ns

, operator+

namespace ns {
    using Func = std::function<MyType()>;

    Func func(
        const Func &lhs, const Func &rhs) {
        return [lhs, rhs]() {
            auto y = lhs() + rhs();
            return y;
        };
    }

} // namespace ns
+4

, ADL , :

cppreference

- , .

:

namespace N {
    namespace M {
        struct foo {};
    }

    void operator+(M::foo, M::foo) {}
}


int main()
{
    N::M::foo f;
    f + f; // Error, enclosing namespace N won't be searched.
}

std, ADL.

, operator+ , , . operator+ namespace ns, , .

+3

Source: https://habr.com/ru/post/1695857/


All Articles