【问题标题】:Use the return type of a method as an argument type of another method in a curiously recurring template class在奇怪重复的模板类中使用方法的返回类型作为另一个方法的参数类型
【发布时间】:2016-02-26 23:48:45
【问题描述】:

请考虑以下代码sn-p:

template<class E>
class vector_expression
{
public:
    auto size() const {
        return static_cast<E const&>(*this).size();
    }

    auto operator[](/* type equal to E::size_type */ i) const
    {
        if (i >= size())
            throw std::length_error("");
        return static_cast<E const&>(*this)[i];
    }
}; // class vector_expression

template<typename T, class Tuple = std::vector<T>>
class vector
    : public vector_expression<vector<T, Tuple>>
{
public:
    using value_type = T;
    using size_type = typename Tuple::size_type;

    size_type size() const {
        return m_elements.size();
    }

    value_type operator[](size_type i) const { /* ... */ }

private:
    Tuple m_elements;
}; // class vector

vector_expression&lt;E&gt; 的参数i 的类型应该等于E::size_type。出于合理的原因,typename E::size_type 在这里不起作用。出于同样的原因,std::result_of_t&lt;decltype(&amp;size)(vector_expression)&gt; 在这里不起作用。

那么,如果我们能做到,我们该怎么做呢?

【问题讨论】:

  • 您的示例在 operator[] 调用中有无限递归。
  • @SimonKraemer 是的,我知道。我已经简化了代码,以便专注于相关部分。但是,为了避免混淆,我已经编辑了代码。

标签: c++ templates c++14 crtp expression-templates


【解决方案1】:

您可以将其作为模板参数显式传递给vector_expression

template<class E, class size_type>
class vector_expression ...

template<typename T, class Tuple = std::vector<T>>
class vector
    : public vector_expression<vector<T, Tuple>, 
                               typename Tuple::size_type> ...

编辑:

也可以把有问题的函数变成一个成员函数模板,这样直到看到完整的类定义才被实例化:

template <typename K = E>
auto operator[](typename K::size_type i) const
{
    if (i >= size())
        throw std::length_error("");
    return static_cast<K const&>(*this)[i];
}

【讨论】:

  • 虽然这在技术上可行,但我希望有一个更优雅的解决方案。
  • 感谢您的编辑。我喜欢你的第二种方法。它不像第一个那样直观,但从我的角度来看更易于维护(因为我们可能在vector_expression 中遇到其他情况,但存在相同的问题,但类型不同(我们需要将其添加到模板参数列表中) ,同样,如果我们遵循第一种方法)。
猜你喜欢
  • 2018-11-27
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 2013-11-12
  • 1970-01-01
  • 2020-09-18
  • 1970-01-01
  • 2011-03-05
相关资源
最近更新 更多