【发布时间】:2013-03-22 15:57:45
【问题描述】:
下面的简单代码编译正常
class A {
int x[3];
public:
A() { x[0]=1; x[1]=2; x[2]=3; }
friend int const&at(A const&a, unsigned i) noexcept
{
return a.x[i];
}
friend int foo(A const&a, unsigned i) noexcept
{
int tmp = at(a,i);
return tmp*tmp;
}
};
但如果朋友是模板
class A {
int x[3];
public:
A() { x[0]=1; x[1]=2; x[2]=3; }
template<unsigned I>
friend int const&at(A const&a) noexcept
{
static_assert(I<3,"array boundary exceeded");
return a.x[I];
}
template<unsigned I>
friend int foo(A const&a) noexcept
{
int tmp = at<I>(a); // <- error: use of undeclared identifier 'at'
return tmp*tmp;
}
};
查找规则发生变化,clang 抱怨说错误,但 gcc 和 icpc 没有。谁是对的(C++11)?以及如何为 clang 修复代码?
【问题讨论】:
-
将函数声明为
friend有什么原因吗? -
试试
::at<I>(a),但你不应该这样做。 -
@JoachimPileborg 当然(这里的代码只是一个简单的例子,可能不存在这样的原因),这就是问题的重点。
-
at需要在周围的命名空间中声明。没有一个的友元函数只能通过 ADL 找到,而当您显式指定模板参数 IIRC 时,这还不会发生。 -
@Dave 不,没有帮助。
标签: c++ templates c++11 clang friend