为什么删除此类型别名中的 const 限定符?
Why is the const qualifier in this type alias dropped?
TL;DR
给定以下类型:
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 上的示例,该示例不应编译。
详情
我有一个模板化的 class,它将一堆迭代器(-types)作为模板参数。我需要从这些迭代器中推导出引用和常量引用类型,因为我有一些成员函数,例如:
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 成员函数,因此编译器会抛出异常。
它是掉线了。我们所说的 "const reference" 实际上是对 const 的引用 - const int&
.
有一个 int&
并添加 const
将得到 int& const
。但是这样一个const被丢弃了。
你的问题类似于const int*
和int* const
的区别。除了引用,int&
和 int& const
是同一类型 - const
被忽略。
你的问题是west const。西方 const 是不好的 const 东方 const 是最好的 const。
West const 是把const 放在你想成为const 的标记的左边。 East const 放在右边。
如果我告诉你永远不要把 const 放在类型的左边,并且 const 总是应用于 它 左边的东西,看看这个:
using const_reference = reference const;
您大概可以弄清楚为什么 const
不起作用。天真地扩展引用后,您会得到 string&const
——这里您尝试将 const
应用于 &
而不是 string
,并且 foo &const
与 foo const&
-- foo&const
只是一个 foo&
,因为 const
不能应用于引用本身,而只能应用于引用的类型。
当然,你说,但这就是我想要 west const 的原因!
West const 在这里做同样的事情。它适用于 &
而不是 string
然后被丢弃。它只是以一种更令人困惑且更难直观理解的方式来实现。
要理解 const,请将您的 const 转换为 east const。 West const 只是标准 east const 规则的一个例外,如果左侧的类型中没有标记,则它适用于右侧的标记。此处右侧的标记是捆绑到类型别名中的整个类型 string&
(类型别名不是宏)。相反,如果您键入 const string&
,则右侧的标记将是 string
,并且您会得到 string const&
以正常的东方常量样式。
East const 是最好的const.
TL;DR
给定以下类型:
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 上的示例,该示例不应编译。
详情
我有一个模板化的 class,它将一堆迭代器(-types)作为模板参数。我需要从这些迭代器中推导出引用和常量引用类型,因为我有一些成员函数,例如:
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 成员函数,因此编译器会抛出异常。
它是掉线了。我们所说的 "const reference" 实际上是对 const 的引用 - const int&
.
有一个 int&
并添加 const
将得到 int& const
。但是这样一个const被丢弃了。
你的问题类似于const int*
和int* const
的区别。除了引用,int&
和 int& const
是同一类型 - const
被忽略。
你的问题是west const。西方 const 是不好的 const 东方 const 是最好的 const。
West const 是把const 放在你想成为const 的标记的左边。 East const 放在右边。
如果我告诉你永远不要把 const 放在类型的左边,并且 const 总是应用于 它 左边的东西,看看这个:
using const_reference = reference const;
您大概可以弄清楚为什么 const
不起作用。天真地扩展引用后,您会得到 string&const
——这里您尝试将 const
应用于 &
而不是 string
,并且 foo &const
与 foo const&
-- foo&const
只是一个 foo&
,因为 const
不能应用于引用本身,而只能应用于引用的类型。
当然,你说,但这就是我想要 west const 的原因!
West const 在这里做同样的事情。它适用于 &
而不是 string
然后被丢弃。它只是以一种更令人困惑且更难直观理解的方式来实现。
要理解 const,请将您的 const 转换为 east const。 West const 只是标准 east const 规则的一个例外,如果左侧的类型中没有标记,则它适用于右侧的标记。此处右侧的标记是捆绑到类型别名中的整个类型 string&
(类型别名不是宏)。相反,如果您键入 const string&
,则右侧的标记将是 string
,并且您会得到 string const&
以正常的东方常量样式。
East const 是最好的const.