考慮以下代碼:如何在朋友功能模板的類定義的情況下避免重新定義錯誤?
template<typename T>
class Base
{
template<typename U>
friend void f(void *ptr) {
static_cast<Base<U>*>(ptr)->run();
}
protected:
virtual void run() = 0;
};
class A : public Base<A>
{
protected:
virtual void run() {}
};
/*
class B : public Base<B>
{
protected:
virtual void run() {}
};
*/
它編譯罰款現在(ideone)。但是,如果我取消的B
定義,那麼它提供了以下錯誤(ideone):
prog.cpp: In instantiation of ‘Base<B>’:
prog.cpp:20: instantiated from here
prog.cpp:6: error: redefinition of ‘template<class U> void f(void*)’
prog.cpp:6: error: ‘template<class U> void f(void*)’ previously defined here
我知道(好,我想我知道)爲什麼它給這個錯誤的原因。
所以我的問題是:
如何避免在類友元函數模板的定義的情況下重新定義錯誤?
只要我在類中提供主模板(非特殊化)的定義,我會得到這個錯誤。也有以這種方式定義主模板另一個問題:它使Base
類模板所有實例,這也是我想避免的f
函數模板friend
的所有實例。我要讓f<T>
的Base<T>
的朋友而不是f<U>
的Base<T>
如果U
和T
不一樣的朋友。同時,我也想在課堂上提供定義。可能嗎?
我不明白爲什麼編譯器應該出錯了那麼一點,似乎鐺人不明白了一個道理也一樣,它編譯與鐺。 – PlasmaHH 2012-02-17 09:25:32
如果我取消註釋「B」的定義,則GCC和MSVC10都會給出錯誤。 – Nawaz 2012-02-17 09:44:18
@PlasmaHH:因爲朋友函數不是成員函數,因此可以不依賴於類模板的參數。 – 2012-02-17 10:49:06