Boost 序列化 base_object 非专用模板 - 为什么它有效?
Boost serialization base_object unspecialized template - why does it work?
我试图理解为什么这个最小的例子可以编译:
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
的模板参数,这又如何编译?
的确,它不是“非专业化”而是“非参数化”,由于语言特性,这实际上是可以的。这种机制被称为 class name injection 并由标准指定。
就像@康桐薇提到的,Base
可以在 class 声明中没有模板参数的情况下使用。
对于一些背景,请参阅例如
我试图理解为什么这个最小的例子可以编译:
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
的模板参数,这又如何编译?
的确,它不是“非专业化”而是“非参数化”,由于语言特性,这实际上是可以的。这种机制被称为 class name injection 并由标准指定。
就像@康桐薇提到的,Base
可以在 class 声明中没有模板参数的情况下使用。
对于一些背景,请参阅例如