请考虑以下代码段:
template<class Tuple>
class vector
{
public:
auto size() const noexcept(noexcept(m_elements.size())) {
return m_elements.size();
}
auto operator[](decltype(size()) i)
{
throw_if_index_out_of_range(i);
return m_elements[i];
}
auto operator[](decltype(size()) i) const
{
throw_if_index_out_of_range(i);
return m_elements[i];
}
private:
void throw_if_index_out_of_range(decltype(size()) i) const
{
if (i >= size())
throw std::length_error("element index out of range");
}
Tuple m_elements;
};
不幸的是,the code above won't compile with clang 3.6 (C++17)。它生成错误消息调用非静态成员函数而没有对象参数。
我们可以保存使用decltype(size())
的想法,还是需要创建一些size_type = decltype(std::declval<Tuple const&>().size())
?
答案 0 :(得分:0)
this
是有效表达式的范围有限,在您的情况下,它开始right after you need it。您可以引入一个对象(各种)以确保对size
的调用有效,扮演隐式this->
的角色:
auto operator[](decltype( std::declval<vector&>().size() ) i);
话虽如此,我反对它 - 即使你有权访问this
,我也会反对它。该声明显然很难阅读和理解,完全没有任何好处。特别要考虑你重复decltype( … )
中的const
- 限定重载,结果是审阅者必须仔细解析在那里测试哪个表达式并回溯到 previous < / em>重载以检查表达式中存在哪些差异(如果有)。
不要重复自己,重构:
using size_type = …; // choose one spec and stick to it
auto operator[](size_type i);
auto operator[](size_type i) const;
size_type
也不必是公共接口的一部分,我们只关心避免重复。