代码
我将问题简化为这个示例(粘贴为单个块以便于编译)
/// \brief The free-function template,
/// which is overloading a method with the same name in AbstractA below.
template <class T>
inline const T overloadedMethod(const T& lhs, const T& rhs)
{
return T(lhs.value+rhs.value);
}
/// \brief AbstractA class
class AbstractA
{
public:
AbstractA (int aVal):
value(aVal)
{}
inline const AbstractA overloadedMethod(const AbstractA &rhs) const
{
return AbstractA(value+rhs.value);
}
protected:
int value;
};
/// \brief A class, deriving from AbstractA,
/// and friending the free-function template.
class A : public AbstractA
{
friend const A overloadedMethod <A>(const A& lhs, const A& rhs);
/// This one gives me compilation error
//template<class T> friend const T overloadedMethod(const T& lhs, const T& rhs);
/// This one would be okay
public:
A (int aVal):
AbstractA(aVal)
{}
};
int main()
{
A a1(1), a2(2);
overloadedMethod(a1, a2);
return 0;
}
细节
基本上,我尝试过的编译器(VS 2010 和 G++ 4.7.2)给我一个错误就行了
friend const A overloadedMethod <A>(const A& lhs, const A& rhs);
他们似乎认为我在声明一个名为的数据成员重载方法。
如果出现以下情况,则不会引发编译错误:
- 我把自由功能模板的非专业版作为朋友(注释的代码行)
- 我从类AbstractA中删除了成员函数overloadedMethod()
问题
我无法解释这种语言行为,所以我的问题是:
- 导致此错误的 C++ 规则是什么?(为什么编译器会认为我在这里声明了一个数据成员?)
- 你知道它背后的理由吗?(我特别想知道如果我从类AbstractA中删除了重载方法() ,为什么它似乎可以工作。或者它是一个 UB 吗?)