- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我将问题简化为这个例子(粘贴为一个 block 以便于编译)
/// \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);
他们似乎认为我正在声明一个名为overloadedMethod 的数据成员。
在以下情况下不会引发编译错误:
我无法解释语言的这种行为,所以我的问题是:
最佳答案
首先,你的基本前提friend
声明是正确的:
[C++11: 14.5.4/1]:
A friend of a class or class template can be a function template or class template, a specialization of a function template or class template, or an ordinary (non-template) function or class. For a friend function declaration that is not a template declaration:
- if the name of the friend is a qualified or unqualified template-id, the friend declaration refers to a specialization of a function template, otherwise
- if the name of the friend is a qualified-id and a matching non-template function is found in the specified class or namespace, the friend declaration refers to that function, otherwise,
- if the name of the friend is a qualified-id and a matching function template is found in the specified class or namespace, the friend declaration refers to the deduced specialization of that function template (14.8.2.6), otherwise,
- the name shall be an unqualified-id that declares (or redeclares) an ordinary (non-template) function.
[ Example:
template<class T> class task;
template<class T> task<T>* preempt(task<T>*);
template<class T> class task {
friend void next_time();
friend void process(task<T>*);
friend task<T>* preempt<T>(task<T>*);
template<class C> friend int func(C);
friend class task<int>;
template<class P> friend class frd;
};[..] —end example ]
您可能会遇到问题,因为名称 overloadedMethod
从基类隐藏全局类——不考虑不同的参数列表,以及基名不代表模板的事实:
[C++11: 3.4.1/9]:
Name lookup for a name used in the definition of a friend function (11.3) defined inline in the class granting friendship shall proceed as described for lookup in member function definitions. If the friend function is not defined in the class granting friendship, name lookup in the friend function definition shall proceed as described for lookup in namespace member function definitions.
[C++11: 3.4.1/10]:
In afriend
declaration naming a member function, a name used in the function declarator and not part of a template-argument in the declarator-id is first looked up in the scope of the member function’s class (10.2). If it is not found, or if the name is part of a template-argument in the declarator-id, the look up is as described for unqualified names in the definition of the class granting friendship.
在这种情况下永远不会触发“如果未找到”子句。
在 GCC 4.8.1 中 this results in the following diagnostic :
error: field ‘overloadedMethod’ has incomplete type
我确定此诊断的具体内容略有错误 — 通过应用 template-parameter-list <A>
,您基本上混淆了编译器到它不认为是模板的东西。
你无法解决这个问题,even by qualifying the friend
declaration :
friend const A ::overloadedMethod<A>(const A& lhs, const A& rhs);
以下确实有效:
friend auto ::overloadedMethod<A>(const A&, const A&) -> const A;
但我认为,根据上述规则,这实际上是一个编译器错误。
关于c++ - 最烦人的 friend ?友化专门的自由函数模板会引发编译错误(重载方法时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18099166/
我是一名优秀的程序员,十分优秀!