Reputation: 3
This is legacy code that likely worked in era 3.2 or 2.8 g++, but no longer. It does still compile under microsoft C/C++ optimizing compiler v.17. The code has also been trimmed down from the original to isolate the salient issue.
in function +=, error: 'to_every' was not declared in this scope
class Matrix {};
class ElementWiseConst
{
public:
ElementWiseConst(const Matrix& m){}
};
class ElementWise : public ElementWiseConst
{
public:
ElementWise(const ElementWise&);
ElementWise(Matrix& m) : ElementWiseConst(m) {}
void operator += (const double val);
friend ElementWise to_every(Matrix& m) { return m; }
};
Matrix& operator += (Matrix& m, const double val) {
to_every(m) += val;
return m;
}
Is this an implicit conversion or scoping that microsoft is incorrectly allowing?
Upvotes: 0
Views: 53
Reputation: 96835
to_every
is defined inside of ElementWise
and thus can only be found via ADL. The compiler will look at the arguments provided and use its associated namespaces and classes to find the name to_every
. The associate classes of Matrix
is Matrix
itself and its associated namespace is the global namespace (assuming it was declared there). ElementWise
needs to be an associated class, thus to_every
cannot be found.
To get this to work you can:
Define to_every
outside of the class.
Make ElementWise
an associated class by making it a template argument (@sehe):
template<class T>
class ADLMatrix {};
using Matrix = ADLMatrix<class ElementWise>;
Upvotes: 1