C ++中的朋友名称解析范围
Friend name resolving scope in C++
这是遗留代码,可能在时代 3.2 或 2.8 g++ 中有效,但不再有效。它仍然在 Microsoft C/C++ 优化编译器 v.17 下编译。该代码也已从原始代码中删减以隔离突出问题。
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;
}
这是否是 Microsoft 错误地允许的隐式转换或作用域?
to_every
定义在 ElementWise
内部,因此只能通过 ADL 找到。编译器将查看提供的参数并使用其关联的命名空间和 classes 来查找名称 to_every
。 Matrix
的关联 classes 是 Matrix
本身,其关联的命名空间是全局命名空间(假设它是在那里声明的)。 ElementWise
需要关联 class,因此找不到 to_every
。
要使其正常工作,您可以:
在 class 之外定义 to_every
。
使 ElementWise
成为关联的 class 通过使其成为模板参数 (@sehe):
template<class T>
class ADLMatrix {};
using Matrix = ADLMatrix<class ElementWise>;
这是遗留代码,可能在时代 3.2 或 2.8 g++ 中有效,但不再有效。它仍然在 Microsoft C/C++ 优化编译器 v.17 下编译。该代码也已从原始代码中删减以隔离突出问题。
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;
}
这是否是 Microsoft 错误地允许的隐式转换或作用域?
to_every
定义在 ElementWise
内部,因此只能通过 ADL 找到。编译器将查看提供的参数并使用其关联的命名空间和 classes 来查找名称 to_every
。 Matrix
的关联 classes 是 Matrix
本身,其关联的命名空间是全局命名空间(假设它是在那里声明的)。 ElementWise
需要关联 class,因此找不到 to_every
。
要使其正常工作,您可以:
在 class 之外定义
to_every
。使
ElementWise
成为关联的 class 通过使其成为模板参数 (@sehe):template<class T> class ADLMatrix {}; using Matrix = ADLMatrix<class ElementWise>;