2016-02-26 20 views
1

請考慮下面的代碼片段:使用方法的返回類型作爲參數類型的另一種方法的一個奇怪的循環模板類

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<E>i應等於E::size_type的。對於一個合理的理由,typename E::size_type不在這裏工作了。出於同樣的原因,std::result_of_t<decltype(&size)(vector_expression)>在這裏不起作用。

那麼,我們如何才能做到這一點,如果我們能做到嗎?

+0

您的示例在運算符[]調用中有無窮遞歸。 –

+0

@SimonKraemer是的,我知道。爲了專注於相關部分,我簡化了代碼。不過,爲了避免混淆,我編輯了代碼。 – 0xbadf00d

回答

2

你可以明確地把它作爲一個模板參數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]; 
} 
+0

雖然這是技術上的工作,我希望會有一個更好的解決方案。 – 0xbadf00d

+0

你的願望就是我的命令,請參閱編輯 –

+0

感謝您的編輯。我喜歡你的第二種方法。這不像第一個那麼直觀,但從我的角度來看更具可維護性(因爲我們可能在'vector_expression'中遇到其他情況,但是具有相同的問題,但是具有不同的類型(我們需要添加到模板參數列表如果我們遵循第一種方法)。 – 0xbadf00d

相關問題