我们可以在另一个成员函数的参数列表中使用成员函数的decltype吗?

时间:2016-03-08 17:05:31

标签: c++ c++14 decltype c++17 return-type-deduction

请考虑以下代码段:

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())

1 个答案:

答案 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也不必是公共接口的一部分,我们只关心避免重复。