为什么不能将模板引用类型用作模板类型别名?

时间:2019-09-06 23:39:41

标签: c++ templates

我目前正在为自定义集合样式类编写一个迭代器。我有一个可变的迭代器类,可以很好地工作,但是我决定最好也实现一个const版本,该版本将阻止对要迭代其内容的对象的修改。我决定使用网上发现的使用条件键入的建议来避免单独的类和代码重复。

我以典型的C ++ 11方式定义了iterator_traits类型别名,该别名将允许代码共享和模板参数依赖的const或可变行为(ItemType是外部容器类上的模板参数):

template<bool Const = false>
class iterator {
public:
    using reference = std::conditional_t<Const, const ItemType &, ItemType &>;
    using pointer = std::conditional_t<Const, const ItemType *, ItemType *>;

    //Rest of the iterator_traits and some other typealiases

    ...

    template<bool _Const = Const>
    std::enable_if_t<_Const, value_type>
    operator*() const
    {
        //Return copy
    }
     //Non-const version
    template<bool _Const = Const>
    std::enable_if_t<!_Const, reference>
    operator*()
    {
        //Return modifiable reference type
    }
    ...
}

我决定尝试通过创建另一个模板类型别名来删除重复的std::conditional_t调用:

template<typename type>
using const_conditional = std::conditional_t<Const, const type, type>;

,然后将所有std::conditional_t<...>替换为const_conditional<some_type_here>。这似乎普遍适用于外部类模板参数ItemType类型,但不适用于外部类类型本身(当其类型是引用时),例如const_conditional<MyCollection<ItemType> &>。编译时,编译器抱怨我放弃了限定词,这意味着const没有被应用,因此我违反了const要求,但是用原始的std::conditional_t代码替换了我的自定义类型别名,并且可以正常工作,我不知道为什么。

我当然可以简单地回到原来使用的std::conditional_t调用中,该调用工作正常,但它们似乎过时且重复,而且我不明白为什么我的自定义typealias会失败。在我的特定情况下,通过互联网进行搜索无法帮助我。任何帮助将由衷的感谢。

1 个答案:

答案 0 :(得分:2)

`<table> <tbody> <tr *ngFor = "let inFile of uploadedFileDetails"> <td>Name from Child: {{inFile.name}}</td> <td>Size from Child: {{inFile.size}}</td> </tr> </tbody> </table>` ItemType&本身就是类型,因此添加const限定符将产生ItemType*(在这种情况下,ItemType& const由于模板参数替换而被忽略)和const分别与预期的ItemType* constconst ItemType&不同。对于后者,您可以使用:

const ItemType*

DEMO


请注意,template <typename type> using const_conditional = std::conditional_t<Const, const type, type>; // ... using reference = const_conditional<ItemType>&; using pointer = const_conditional<ItemType>*; 是保留的标识符,其他所有标识符都以下划线开头,后跟大写字母。