本文介绍了模板化的朋友函数查找的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下简单代码编译良好

The following simple code compiles fine

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)?

the look-up rules change and clang complains with said error, but gcc and icpc don't. Who is right (C++11)? and how to get the code fixed for clang?

推荐答案

修复是单独声明和定义:

The fix is to separate declaration and definition:

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;

  template<unsigned I>
  friend int foo(A const&a) noexcept;
};

template<unsigned I>
int const&at(A const&a) noexcept
{
  static_assert(I<3,"array boundary exceeded");
  return a.x[I];
}

template<unsigned I>
int foo(A const&a) noexcept
{
  int tmp = at<I>(a);
  return tmp*tmp;
}

这篇关于模板化的朋友函数查找的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 18:29