[英]Template partial specialisation not working with typedefs
在此示例中:
template<typename T>
struct ConditionalValue
{
typedef boost::optional<T> type;
};
template<typename T>
struct FindRootValueType
{
typedef typename T::root_type type;
};
template<typename T>
struct FindRootValueType<typename ConditionalValue<T>::type>
{
typedef typename ConditionalValue<T>::type type;
};
template<typename T>
struct Base
{
typedef T value_type;
typedef typename FindRootValueType<value_type>::type root_type;
std::vector<value_type> data;
};
template<typename T>
struct A : public Base<typename ConditionalValue<T>::type>
{
};
template<typename T>
struct B : public Base<A<T>>
{
};
template<typename T>
struct C : public Base<B<T>>
{
};
// C<int>::value_type == B<int>
// C<int>::data == std::vector<B<int>>
// C<int>::data ~= std::vector<std::vector<std::vector<boost::optional<int>>>>
// C<int>::root_type == boost::optional<int>
ConditionalValue
是一个模板别名,它只是尝试为boost::optional
提供一个替代名称(以便可以使用其他名称来替代它),而FindRootValueType
是一个元函数,旨在查找定义与那些相似的类型的链。在底部显示,直到停在boost::optional
,然后简单地返回它。
但是,按照本文所述,这行不通(至少在VS2008中不行)。 要解决此问题,FindRootValueType的特殊化必须显式使用boost::optional<T>
,而不是应该与之等效的typedef。 (这违背了只在一个地方指定基础实现类型的目标。)
这是编译器错误还是应该不起作用? 还是我做错了什么? 有没有更好的方式编写它以使其按预期工作?
我还尝试了逆转逻辑:
template<typename T>
struct FindRootValueType
{
typedef T type;
};
// define Base here
template<typename T>
struct FindRootValueType<Base<T>>
{
typedef typename T::root_type type;
};
// define A here
template<typename T>
struct FindRootValueType<A<T>>
{
typedef T type;
};
// define B, C here (no specialisation)
但这也不起作用(我认为因为专业化不遵循基本类型,或者可能只是定义的顺序)。 我不想专门针对B,C等。
(顺便说一句,在以上两种情况中,“ BTW均不起作用”表示产生了编译器错误,表明它使用的是FindRootValueType
的基本定义,而不是专业化。)
受相关问题链接答案的启发,我尝试了以下方法,但似乎可行:
template<typename T>
struct HasRootType
{
private:
typedef char no;
struct yes { no m[2]; };
static T* make();
template<typename U>
static yes check(U*, typename U::root_type* = 0);
static no check(...);
public:
static bool const value = sizeof(check(make())) == sizeof(yes);
};
template<typename T, bool = HasRootType<T>::value>
struct FindRootValueType
{
typedef typename T::root_type type;
};
template<typename T>
struct FindRootValueType<T, false>
{
typedef T type;
};
// define Base, A, B, C, etc here
因此,将问题重新定义为“遍历类型,直到找到没有root_type
的类型,然后将其返回”。 我仍然很好奇为什么基于typedef的专业化似乎不起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.