Nachschlagen der Freundfunktion als Vorlage

Der folgende einfache Code wird problemlos kompiliert

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;
  }
};

aber wenn die freunde zu vorlagen gemacht werden

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;
  }
};

Die Nachschlage-Regeln ändern sich und klirren mit dem besagten Fehler, aber das tun gcc und icpc nicht. Wer hat Recht (C ++ 11)? und wie kann man den Code für clang reparieren lassen?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage