我目前正在为自定义集合样式类编写迭代器。我有一个工作完美的可变迭代器类,但决定最好也实现一个 const 版本,该版本将阻止修改其内容正在被迭代的对象。我决定通过使用我在网上找到的使用条件类型的建议来避免单独的类和代码重复。
我定义了 iterator_traits
典型 C++11 方式中的类型别名将允许代码共享和依赖于模板参数的常量或可变行为(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
我最初使用的调用效果很好,但它们看起来臃肿且重复,而且我不明白为什么我的自定义类型别名失败了。在我的具体情况下,互联网上的搜索未能帮助我。任何帮助将不胜感激。
最佳答案
ItemType&
和 ItemType*
本身就是类型,因此添加 const 限定符会产生 ItemType& const
(在这种情况下 const
由于模板参数替换而被静默忽略)和 ItemType* const
,这与预期的 const ItemType&
和 const ItemType*
。对于后者,您可以使用:
template <typename type>
using const_conditional = std::conditional_t<Const, const type, type>;
// ...
using reference = const_conditional<ItemType>&;
using pointer = const_conditional<ItemType>*;
作为旁注,_Const
是一个保留标识符,因为所有其他标识符都以下划线开头,后跟大写字母。
关于c++ - 为什么不能将模板引用类型用作模板类型别名参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57829565/