這在過去的幾個小時裏一直令我瘋狂,我似乎無法解決這個問題。我將這個問題歸結爲這60行代碼(包括一個主函數)。在另一個命名空間和CRTP中的模板好友功能
#include <iostream>
namespace n1 {
// the general definition
template <class X, class Y> void f(X&, const Y&)
{
std::cout << "general template definition.\n";
}
} // namespace n1
namespace n2 {
// CRTP
template <class Derived> class A
{
int data;
// partial function template specialization for n1::f, and declare
// it a friend too, so that it may access the data attribute of A
template <class Y> friend void n1::f(A<Derived>& a, const Y& y);
}; // class A
} // namespace n2
namespace n1 {
// implementation for this particular function template specialization
template <class Derived, class Y> void f(n2::A<Derived>& a, const Y& y)
{
std::cout << "partial template specialization: " << a.data << "\n";
}
} // namespace n1
namespace n2 {
// Another class!
class B : public A<B>
{
}; // class B
} // namespace n2
namespace n1 {
// --------------------
// tricky part is here!
// --------------------
template <class Y> void f(n2::B& b, const Y& y)
{
// FAIL! not a friend! How?
f(static_cast<n2::A<n2::B>&>(b), y);
}
} // namespace n1
int main()
{
n2::B b;
int x;
n1::f(b, x); // should print "partial template specialization"
return 0;
}
所以,我「想」是可以讓編譯器選擇n1::f
我的函數模板專業化每當這與一種A<Derived>
具體子類調用。爲了確保編譯器支持我的專業化,我需要爲每個子類(在這種情況下爲B
)提供一個n1::f
的模板專用,它可以簡單地委託調用。當發生這種情況時,我預計A<Derived>
的data
成員變量可被n1::f
訪問,因爲我聲明n1::f
是A<Derived>
的朋友。但是,海灣合作委員會抱怨A<Derived>::data
是私人的,無法訪問,see this snippet on Coliru。
這是可行的嗎?如果是這樣,我怎麼能繞過編譯器抱怨A<Derived>::data
不可訪問? (讓它公開不是一種選擇)。
我看到...這個工程!哇。你能解釋爲什麼額外的模板參數'D'是必需的嗎?它在我看來像我的朋友聲明會使任何'A'成爲朋友,但似乎你需要一個單獨的模板參數。 –
rwols
@rwols我增加了更多細節。它們是兩個不同的函數模板,因爲它們具有不同的模板參數列表和不同的參數。我不知道如何更好地解釋它... – skypjack
謝謝,我認爲這爲我解決了一些問題。 – rwols