为什么模板引用类型不能用作模板类型别名参数?
Why can't a template reference type be used as a template typealias argument?
我目前正在为自定义集合样式类编写迭代器。我有一个运行良好的可变迭代器类,但决定最好也实现一个 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
调用,它工作正常,但它们似乎臃肿和重复,我不明白为什么我的自定义类型别名失败。在我的特定情况下,互联网上的搜索未能帮助我。任何帮助将不胜感激。
ItemType&
和ItemType*
本身就是类型,因此添加常量限定符分别产生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++编译器该参数没有别名
- 为什么我们不能重复使用具有不同模板参数的别名模板标识符?
- C++模板/别名 - 模板参数列表中参数 1 处的类型/值不匹配
- 模板模板参数和模板别名:编译器错误?
- 为模板参数包添加别名
- C++使用默认模板参数键入别名和转发声明
- 缺少别名模板C++参数列表
- 使用外部定义的模板类型作为模板参数的更通用模板的模板别名
- 必须非常量别名参数及其默认参数常量
- 作为模板参数 c++ 给出的类的别名模板
- 使用其他模板类型参数作为要在函数签名中使用的类型别名声明
- 参数化类的别名(或类型定义)内部类
- C++别名的模板参数包扩展
- 如何简化模板模板参数中的enable_if别名
- 包含可变参数包的第一个可转换类型的别名的结构
- C++ 11 个模板,参数包的别名
- 为什么模板引用类型不能用作模板类型别名参数?
- 具有模板类默认参数的 C++17 别名模板
- 模板别名、变量模板和自动类型推断无法推断模板参数