【问题标题】:make another instatiation's friend of a template class使另一个实例成为模板类的朋友
【发布时间】:2011-02-25 14:25:55
【问题描述】:
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);
}

上面的代码不能用 g++ 和 Como 编译。 g() 在这里展示我想用 f() 做什么。

例如,这里是 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

还有科莫的:

"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".

错误消息建议的变体也没有。

顺便说一句,我知道明显的解决方法

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

编辑:

14.5.4/5(n3225的,C++98的14.5.3/6类似,但n3225下面的文字更清楚)开始

类模板的成员可以声明为非模板类​​的朋友...

这可能意味着类模板的成员可能不会被声明为模板类的朋友,但我的第一个解释是这句话是对以下解释的介绍(主要它们适用于任何专业化,明确与否,给定原型是正确的)。

【问题讨论】:

  • @Johannes Schaub,相似但不同。正如我对 Ise 建议的评论,我想要的是 Foo 的 Foo::f 朋友,而不是 Foo 的 Foo::f 朋友。我不会对转换运算符为编译器增加额外的复杂性感到惊讶。

标签: c++ templates friend


【解决方案1】:

我认为你必须在朋友声明之前说template &lt;&gt;,这样它就知道你在交友一个专业。

编辑:我的代码没有任何错误,即使进行实例化并调用g。您能否发布导致错误的最小实际代码集以及错误消息?

【讨论】:

  • 我试过了。它不起作用,我想知道为什么 g 也不需要它?
  • 完成。同样,问题不在于 g(),而在于 f()。我给 g() 是为了展示我想要的东西,但有一个免费的功能。
【解决方案2】:

虽然我不能 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 );
}

希望这会有所帮助。

【讨论】:

  • 是的,但这会让每个 Foo::f 成为 Foo 的朋友。我希望只有 Foo:f 是 Foo 的朋友。
  • 对不起,我误解了这个问题。
  • 顺便说一句,您的意图可能无法在当前的 C++ 中实现。我想声明 Foo&lt;U&gt;::f&lt;T&gt; 类似于专门化 f 之前封闭类模板是专门的。如果这种解释是相关的,那么在当前的 C++ 中无法做到这一点......
  • 这可能是一个提示。但是,当试图让朋友成为另一个完全指定的类的特化时,问题也存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
  • 1970-01-01
相关资源
最近更新 更多