给出以下类型:
struct A
{
std::vector<std::string> vec;
using reference = std::iterator_traits<decltype(vec)::iterator>::reference;
using const_reference = const reference;
};
为什么reference == const_reference
?为什么const
限定符会在第二个类型别名中删除?
请参阅godbold上不应该编译的示例。
我有一个模板化的类,它将一堆迭代器(-types)作为模板参数。从这些迭代器我需要推导出引用和const引用类型,因为我有一些成员函数,如:
struct A
{
std::vector<std::string> vec;
using reference = std::iterator_traits<decltype(vec)::iterator>::reference;
using const_reference = const reference;
const_reference foo() const
{
return vec[0];
}
};
通过删除const
限定符,我有效地返回foo
中的引用,这是非法的,因为它是一个const成员函数,因此编译器会抛出。
答案 0 :(得分:7)
被删除。我们称之为&#34; const参考&#34;实际上是对const的引用 - const int&
。
拥有int&
并添加const
即可int& const
。但这样的常数被删除了。
您的问题类似于const int*
和int* const
之间的差异。除了引用之外,int&
和int& const
属于同一类型 - const
会被忽略。
答案 1 :(得分:4)
你的问题是西const。西const是坏const const const const是最好的const。
West const将const放在你想成为const的令牌的左边。东方const正在把它放在右边。
如果我告诉你永远不要在你的类型的左边放置const,并且const总是适用于其左边的东西,那么看看:
using const_reference = reference const;
你可能会弄清楚const
无效的原因。天真地扩展参考后,您得到string&const
- 在这里您尝试将const
应用于&
而不是string
,而foo &const
与foo const&
不同{1}} - foo&const
仅为foo&
,const
无法应用于引用本身,但仅适用于引用的类型。
当然,你说,但这就是我想要西方const的原因!
West const 在这里做同样的事情。它适用于&
而不是string
,然后被丢弃。它只是以一种更加混乱,更难以直观地掌握的方式来实现。
要理解const,请将const转换为east const。 West const只是标准east const规则的一个例外,如果左边的类型中没有令牌,则它适用于右边的令牌。此处右侧的标记是捆绑在类型别名中的整个类型string&
(类型别名不是宏)。如果您键入const string&
,则右侧的标记为string
,您将以健全的东方风格获得string const&
。
东方const是最好的常量。