[英]In C++, why isn't it possible to friend a template class member function using the template type of another class?
換句話說,為什么編譯正常:
template<typename Type>
class A{
public:
void f();
};
class B{
friend void A<int>::f();
};
template<>
void A<int>::f(){
B* var = new B();
}
雖然這不是:
template<typename Type>
class A{
public:
void f();
};
template<typename Type> // B is now a templated class
class B{
friend void A<Type>::f(); // Friending is done using B templated type
};
template<>
void A<int>::f(){
B<int>* var = new B<int>(); // var is now declared using int as its templated type
}
對於第二個代碼片段,編譯器(gcc 6.2,沒有特殊標志)說:
main.cpp: In instantiation of ‘class B<int>’:
main.cpp:14:28: required from here
main.cpp:9:15: error: prototype for ‘void A<int>::f()’ does not match any in class ‘A<int>’
friend void A<Type>::f();
^~~~~~~
main.cpp:13:6: error: candidate is: void A<Type>::f() [with Type = int]
void A<int>::f(){
據我所知,在第二個代碼片段中,當聲明var時,編譯器應該解析B類聲明,用int替換友元聲明中使用的Type,一切都應該正常工作。 我錯過了什么?
編輯:下面的評論指出,第二個代碼片段似乎與clang和Visual C ++ 2015正確編譯
在A<int>::f()
使用B<int>
之前的顯式實例化可以解決此問題。 我假設GCC在A<int>::f()
的定義中嘗試隱式實例化B<int>
。 但是A<int>::f()
的定義沒有完成,GCC'丟失'了朋友聲明。 它看起來像編譯器問題。
template<typename Type>
class A
{
public:
void f();
};
template<typename Type> // B is now a templated class
class B
{
friend void A<Type>::f(); // Friending is done using B templated type
};
template
class B<int>; // <= explicit instantiation, that works
template<>
void A<int>::f()
{
B<int>* var = new B<int>();
}
專業template class
成員函數沒有專門的整個template class
是特殊情況,當你被允許專門化非template
成員函數,所以也許GCC
很困惑,我不知道原因,但不知何故你不能聲明友誼到專業template class
非template
成員。 臨時解決方案是專門為整個class template
工作。
//class template A
template<typename Type>
class A{
public:
void f();
};
//class A<int>
template<>
class A<int>{
public:
void f();
};
然后,定義A<int>::f
:
對於class B:
void A<int>::f(){
B* var = new B();
(void)(var);
}
對於template class B
:
void A<int>::f(){
B<int>* var = new B<int>();
(void)(var);
}
但我認為Clang
就在這里,對於這樣的朋友宣言應該沒有問題。 這可能是GCC
的一個錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.