2017-08-14 46 views
0

的存在我本來想它是否有或沒有const修飾聲明一個類中的演繹。正如你們許多人指出的那樣,它是被聲明爲const(而不是類)的變量本身。感謝您澄清這一點。現在的錯誤信息對我完全有意義。所以,這更多的是設計問題。GCC7推斷在同一類中的const修飾

我想要的是一個結構,其行爲像一個隨機存取容器,並提供一些功能,如iterator begin(){...},const_iterator cbegin(){...},特別是value_type operator[](size_type idx){...}等等。我想提供儘可能多的功能,無論實例是否爲常量。因此,在實踐中A a{}; a.begin();將返回Aa.cbegin()一個常量引用值類型的非恆定的參考。而A const ac{};ac.begin()ac.cbegin()應該具有相同的常量參考類型。但是這些用例可能沒有意義。 予可能會限制使用,其中只有非c​​onst a與非const迭代組合是可調用的情況下(即允許a.begin(),但不是a.cbegin())和ac只與常量迭代(即ac.cbegin(),但不是ac.begin())。這有道理嗎?

後面這個奇怪的嘗試的原因是,在我的實現不存在ONE基礎容器,但兩個輔助容器:一個位向量和壓縮序列。根據位矢量的內容,我要麼返回一個特殊符號,要麼返回壓縮序列的一個字母(參見擴展代碼示例)。 另外,我不使用std :: iterator,而是使用自己的實現。注意(*host)[idx + offset]返回一個臨時的,這可能是爲什麼我在輸出後得到一個分段錯誤。

#include <cassert> 
#include <iostream> 
#include <numeric> 
#include <type_traits> 
#include <vector> 

template<typename container_t> 
struct my_iterator 
{ 
private: 
    using reference = std::conditional_t<std::is_const<container_t>::value, 
        typename container_t::const_reference, 
        typename container_t::reference>; 
    using size_type = typename container_t::size_type; 
    size_type offset = 0; 
    typename std::add_pointer_t<container_t> host{nullptr}; 
public: 
    my_iterator(container_t & host_, size_type offset_) : host{&host_}, offset{offset_} {} 
    reference operator[](typename container_t::size_type const idx) 
    { 
     return (*host)[idx + offset]; 
    } 
}; 

template<typename sequence_t> 
struct A // implements some features of the container concept 
{ 
    using const_reference = typename sequence_t::const_reference; 
    using reference = typename sequence_t::value_type; 
    using iterator = my_iterator<A>; 
    using const_iterator = my_iterator<A const>; 
    using value_type = typename sequence_t::value_type; 
    using size_type = typename sequence_t::size_type; 

    // data structures internally used to resolve random access 
    std::vector<unsigned int> bit_vector{1,0,1,0,0,0}; 
    std::vector<char> text{'h', 'w'}; 
    constexpr char static const cash = '$'; 

public: 
    // provide some container functions, like begin, end, cbegin, cend 
    iterator begin() 
    { 
     return iterator{*this, 0}; 
    } 

    const_iterator cbegin() const 
    { 
     return const_iterator{*this, 0}; 
    } 
    // ... 

    size_type rank(size_type idx) const 
    { 
     return std::accumulate(bit_vector.begin(), bit_vector.begin()+idx, 0); 
} 

constexpr reference operator[](size_type const idx) const 
{ 
    assert(idx < bit_vector.size()); 
    if (bit_vector[idx]) 
     return cash; 
    return text[idx - rank(idx)]; 
} 
}; 

int main(){ 
    /* non const usage */ 
    A<std::vector<char>> a{}; 
    auto it_a = a.begin(); 
    std::cout << it_a[0] << std::endl; 
    /* const usage */ 
    A<std::vector<char>> const a_const{}; 
    /* does not compile, because of non matching types */ 
    auto it_const_a = a_const.begin(); 
    std::cout << "it_const_a[0] = " << it_const_a[1] << std::endl; 
    /* does compile, but gives segmentation fault */ 
    auto it_const_a2 = a_const.cbegin(); 
    std::cout << "it_const_a2[0] = " << it_const_a2[1] << std::endl; 
} 
+3

'此'只存在於成員函數中;這是對象意識到自身存在的唯一情況。你想要這個的理由聽起來有點奇怪。如果你解釋這個和重載'[]'操作符之間的連接,你可能會得到解決你實際問題的幫助。 – molbdnilo

+0

也,'A <性病::矢量>一();'是一個函數的返回的聲明'A <性病::矢量>'。你應該寫'A > a;'而不是。 – WindyFields

+0

你不能做你建議的事情,因爲'const'適用於變量,而不是類。但這絕對是一個X-Y問題。目前還不清楚你究竟在做什麼,但也許你可以用'ret_type1 operator [](size_t);''和'ret_type2 operator [](size_t)const;'重載獲得你所需要的。 – aschepler

回答

2

我想它是否有或沒有const修飾聲明一個類中的演繹。

不與const詞聲明。這些限定詞用於聲明變量

有非靜態成員函數之外沒有this,作爲錯誤消息解釋。類的成員類型(別名)不依賴於實例,因此不能依賴於實例的常量。

在任何情況下,我懷疑你認爲std::iterator是一個迭代器。它是而不是的一個迭代器。它是一個基類,可用於避免在編寫(自定義)迭代器時重複一些定義。而這種混亂可能是它在即將到來的標準版本中被棄用的原因。