具有模板类型的 C++ TypeList 具有不能一起使用的索引和类型操作

问题描述 投票:0回答:1

对于我正在从事的项目,我一直在尝试实现一个以模板类作为可能类型的类型列表,我的实现的相关部分如下。它通常运行良好,但当我将一些实用程序类型/操作组合在一起时,它无法按预期运行。

// template class typelist
template <template <class> class ... TemplateTypes>
struct TemplateTypeList {};

// utility types for TemplateTypeList
// type at index of typelist
template <std::size_t I, class TypeList>
struct TemplateTypeListType;

template <template <class> class First, template <class> class ... RestOfTypeList>
struct TemplateTypeListType<0, TemplateTypeList<First, RestOfTypeList...>> {
    template <class T>
    using result = First<T>;
};

template <std::size_t I, template <class> class First, template <class> class ... RestOfTypeList>
struct TemplateTypeListType<I, TemplateTypeList<First, RestOfTypeList...>> {
    template <class T>
    using result = typename TemplateTypeListType<I - 1, TemplateTypeList<RestOfTypeList...>>::template result<T>;
};

// index of type in typelist
template <template <class> class TypeToFind, class TypeList>
struct TemplateTypeListIndex;

template <template <class> class TypeToFind, template <class> class ... RestOfTypes>
struct TemplateTypeListIndex<TypeToFind, TemplateTypeList<TypeToFind, RestOfTypes ...>> {
    static const int result = 0;
};

template <template <class> class TypeToFind, template <class> class First, template <class> class ... RestOfTypes>
struct TemplateTypeListIndex<TypeToFind, TemplateTypeList<First, RestOfTypes...>> {
    private:
        using ResultOfPrior = TemplateTypeListIndex<TypeToFind, TemplateTypeList<RestOfTypes...>>;
    public:
        static const int result =  ResultOfPrior::result == -1 ? -1 : ResultOfPrior::result + 1;
};

template <template <class> class TypeToFind>
struct TemplateTypeListIndex<TypeToFind, TemplateTypeList<>> {
    static const int result = -1;
};

该实现对于我的大多数情况都工作正常,但是当我使用

TemplateTypeListIndex
并得到
TemplateTypeListType
的结果时,它似乎不起作用,这是一个示例:

template <class T>
struct Class1 {};

template <class T>
struct Class2 {};

using Types = TemplateTypeList<Class1, Class2>;

int index = TemplateTypeListIndex<TemplateTypeListType<0, Types>::result, Types>::result;

ASSERT_EQ(index, 0); // fails, index == -1

我很困惑,因为它几乎适用于我用过的所有其他情况。我对模板专业化所做的一些假设是否不正确,导致了这个问题?

c++ templates template-meta-programming template-templates typelist
1个回答
0
投票

正如评论中所指出的,这似乎是 C++ 规范中 temp.alias 部分的结果,该部分基本上规定模板别名不能相等,只有模板特化可以相等。为了解决这个问题,我在

TemplateTypeListIndex
中创建了一个虚拟专业化,现在将
TemplateTypeListType
TemplateTypeListIndex
结合使用:

// index of type in typelist
template <template <class> class TypeToFind, class TypeList>
struct TemplateTypeListIndex;

template <template <class> class TypeToFind, template <class> class First, template <class> class ... RestOfTypes>
struct TemplateTypeListIndex<TypeToFind, TemplateTypeList<First, RestOfTypes...>> {
    private:
        using ResultOfPrior = TemplateTypeListIndex<TypeToFind, TemplateTypeList<RestOfTypes...>>;
        template <class T>
        using IsMatch = std::is_same<TypeToFind<T>, First<T>>;
        struct Dummy {};
    public:
        static const int result =  IsMatch<Dummy>::value ? 0 : ResultOfPrior::result == -1 ? -1 : ResultOfPrior::result + 1;
};

template <template <class> class TypeToFind>
struct TemplateTypeListIndex<TypeToFind, TemplateTypeList<>> {
    static const int result = -1;
};

我现在意识到,由于 temp.alias 的原因,需要谨慎使用

TemplateTypeListType::result
,并且我应该只使用结果的特化来比较模板特化中的类型。

© www.soinside.com 2019 - 2024. All rights reserved.