繁体   English   中英

模板部分专业化不适用于typedef

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM