简体   繁体   English

成为模板类的另一个实例的朋友

[英]make another instatiation's friend of a template class

template <typename T> class Foo;    
template <typename T> int g(Foo<T> const&);

template <typename T> class Foo
{
public:
    template <typename U> int f(Foo<U> const& p) const { return p.m; }

    // which friend declaration will allow the above function to compile? The
    // next one doesn't work.
    template <typename U> friend void Foo<U>::template f<T>(Foo<T> const&) const;

    // while this one work for g().
    friend int g<T>(Foo<T> const&);

private:
    int m;
};

template <typename T> int g(Foo<T> const& p) { return p.m; }

// Let's call them
void bar()
{
    Foo<int> fi;
    Foo<double> fd;
    fd.f(fi);
    g(fi);
}

The above doesn't compile with g++ nor Como. 上面的代码不能用g ++或Como编译。 g() is here to show what I would like to do with f(). g()在这里显示我想对f()进行的操作。

For instance, here are g++ messages: 例如,以下是g ++消息:

foo.cpp:11: error: invalid use of template-id ‘f<T>’ in declaration of primary template
foo.cpp: In member function ‘int Foo<T>::f(const Foo<U>&) const [with U = int, T = double]’:
foo.cpp:27:   instantiated from here
foo.cpp:17: error: ‘int Foo<int>::m’ is private
foo.cpp:7: error: within this context

and como's one: 还有como的:

"ComeauTest.c", line 11: error: an explicit template argument list is not allowed on
          this declaration
      template <typename U> friend void Foo<U>::template f<T>(Foo<T> const&) const;
                                        ^

"ComeauTest.c", line 7: error: member "Foo<T>::m [with T=int]" (declared at line 17)
          is inaccessible
      template <typename U> int f(Foo<U> const& p) const { return p.m; }
                                                                    ^
          detected during instantiation of "int Foo<T>::f(const Foo<U> &)
                    const [with T=double, U=int]" at line 27

2 errors detected in the compilation of "ComeauTest.c".

Variants suggested by the error messages didn't either. 错误消息建议的变体也没有。

BTW, I know of the obvious work around 顺便说一句,我知道周围的明显工作

template <typename U> friend class Foo<U>;

Edit: 编辑:

14.5.4/5 (of n3225, 14.5.3/6 of C++98 is similar but the following text is clearer in n3225) starts by (n3225的14.5.4 / 5,C ++ 98的14.5.3 / 6相似,但n3225中的以下文本更清楚)以

A member of a class template may be declared friend of a non-template class... 类模板的成员可以声明为非模板类​​的朋友...

which could imply that a member of a class template may not be declared friend of a template class but my first interpretation would that this sentence was an introduction for the following explanations (mainly they apply to any specialisation, explicit or not, given that the prototype is correct). 这可能意味着不能将类模板的成员声明为模板类的朋友,但是我的第一个解释是,这句话是以下解释的导言(主要是,无论原型是显式的还是非显式的,它们都适用于任何专业化知识)是正确的)。

I think you have to say template <> before the friend declaration so it knows you're friending a specialization. 我认为您必须在好友声明之前说出template <> ,这样它才能知道您正在与某个专业领域建立友谊。

EDIT: I can't get any error with your code, even making an instantiation and calling g . 编辑:即使您进行实例化并调用g ,我也无法获得任何错误。 Can you post a minimal set of actual code that's causing the error, along with the error message? 您是否可以发布导致错误的最少实际代码集以及错误消息?

Though I'm not 100% sure this is strictly standard conforming, the following code can be compiled by ideone(gcc-4.3.4) and Comeau online: 尽管我不确定100%是否严格遵循标准,但是以下代码可以由ideone(gcc-4.3.4)和Comeau在线进行编译:

template< class >
class Foo {
  int m;
 public:
  template< class U > int f( Foo<U> const& p ) const { return p.m; }
  template< class U > template< class V >
  friend int Foo<U>::f( Foo<V> const& ) const;
};

void bar() {
  Foo<int> fi;
  Foo<double> fd;
  fd.f( fi );
}

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM