我試圖理解為什么這個最小的例子編譯:
https://godbolt.org/z/xYeo53GPv
template <typename T>
struct Base {
friend class boost::serialization::access;
template <class ARCHIVE>
void serialize(ARCHIVE& ar, const unsigned int /*version*/) {}
};
struct Derived : public Base<int> {
friend class boost::serialization::access;
template <class ARCHIVE>
void serialize(ARCHIVE& ar, const unsigned int /*version*/) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
}
};
既然Base是模板型別,怎么可能在BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base)不指定模板引數的情況下將其傳入?
作為參考,在 Boost 1.77 中,宏擴展為
#define BOOST_SERIALIZATION_BASE_OBJECT_NVP(name) \
boost::serialization::make_nvp( \
BOOST_PP_STRINGIZE(name), \
boost::serialization::base_object<name >(*this) \
)
并boost::serialization::base_object定義為:
template<class Base, class Derived>
typename detail::base_cast<Base, Derived>::type &
base_object(Derived &d)
{
BOOST_STATIC_ASSERT(( is_base_and_derived<Base,Derived>::value));
BOOST_STATIC_ASSERT(! is_pointer<Derived>::value);
typedef typename detail::base_cast<Base, Derived>::type type;
detail::base_register<type, Derived>::invoke();
return access::cast_reference<type, Derived>(d);
}
哪里Base是Base(我認為)被明確替換為Base并被Derived推斷為Derived。
重申一下,即使我們指定了 的模板引數,它如何編譯Base?
uj5u.com熱心網友回復:
事實上,它不是“非專業化”而是“非引數化”,由于語言特性,這實際上是可以的。這種機制稱為類名注入,由標準指定。
就像@康桓偉提到的,Base可以在類宣告中沒有模板引數的情況下使用。
有關一些背景,請參見例如
- https://en.cppreference.com/w/cpp/language/injected-class-name
- C 類名注入
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/375302.html
下一篇:模板非型別模板引數
