2012-03-18 116 views
4

我有以下简化代码:朋友模板函数

template <class T> 
class A 
{ 
public: 
    template <class U> 
    static U foo(T* p) 
    { 
     p; 
     return U(); 
    } 
}; 

class B 
{ 
    /*template <class T> 
    template <class U> 
    friend U A<T>::foo<U>(T*);*/ 
    friend B A<B>::foo<B>(B*); 
    B() 
    {} 
public: 
}; 
... 
A<B>::foo<B>(nullptr); 

而且它工作得很好。但是,我没有能够做到的事情评论说:

/*template <class T> 
template <class U> 
friend U A<T>::foo<U>(T*);*/ 

我不知道语法我应该用什么做它的工作原理。所以我需要将我的朋友声明概括为所有可能的类型。我已经尝试了不少的语法变体,但没有成功。有人可以指出我应该写什么,而不是使用我的评论代码来使其有效吗? 谢谢!

+1

'template '? – Vlad 2012-03-18 13:42:30

+0

我尝试了几种不同编译器的变体,似乎没有任何工作(并且生成的错误消息没有帮助)。 – Vlad 2012-03-18 14:45:29

+0

我试过你的代码在叮当2.8和g ++ 4.5.2的Linux上,并且都很满意你的代码... – 2012-03-18 18:27:59

回答

2

什么你要找的是

template <class T> 
template <class U> 
friend U A<T>::foo(T*); 

上IdeOne.com

以下工作
#include <iostream> 

template <class T> 
class A 
{ 
public: 
    template <class U> 
    static U foo(T* p) 
    { 
    p; 
    return U(); 
    } 
}; 

class B 
{ 
    template <class T> 
    template <class U> 
    friend U A<T>::foo(T*); 

    B() {} 

public: 
    void hello() const 
    { 
    std::cout << "I'm a B!" << std::endl; 
    } 
}; 

int main(int, char*[]) 
{ 
    A<B>::foo<B>(NULL).hello(); 
} 
+0

确实:http://ideone.com/fNVaK。仍然想知道为什么模板的语法很模糊,为什么'template template '和'template '之间有区别。 – Vlad 2012-03-19 09:38:18

+0

恩,谢谢!但它仍然不能在MSVC2011上编译。所以现在的问题是:无论是MSVC错误还是gcc“扩展”。 – ixSci 2012-03-19 11:35:28

+0

似乎是一个MSVS错误,因为它在come come上成功编译 – ixSci 2012-03-19 11:39:36

0

我会干脆不混合行吟诗人评论者,朋友和模板同意,在至少在一系列编译器中没有任何一致的方式。该标准可能确切地说应该工作,虽然这可能不会帮助你。悲伤但真实。

无论如何,朋友往往不是一个好主意,不妨考虑如何编写没有友谊的代码,或者使用公共方法的“穷人的朋友”,并注明它不是一般用途。