2015-07-15 17 views
8

Hem const hem de const olmayan erişim sağlayan bir görünüm oluşturmak için view_facade (range-v3'dan) kullanarak sorun yaşıyorum.Aralık-v3: Hem const hem de non-const yineleyicileri sağlamak için view_facade kullanın

struct MyRange 
    : ranges::range_facade<MyRange> 
{ 
private: 
    friend struct ranges::range_access; 
    std::vector<int> ints_; 

    template <bool isConst> 
    struct cursor 
    { 
    private: 
     using It = typename std::conditional<isConst, std::vector<int>::const_iterator, std::vector<int>::iterator>::type; 
     using RefType = typename std::conditional<isConst, int const&, int&>::type; 
     It iter; 
    public: 
     cursor() = default; 
     cursor(It it) 
      : iter(it) 
     {} 
     RefType current() const 
     { 
      return *iter; 
     } 
    //... 
    }; 
/* // Uncommenting these overloads will cause an error, below. 
    cursor<true> begin_cursor() const 
    { 
     return {ints_.begin()}; 
    } 
    cursor<true> end_cursor() const 
    { 
     return {ints_.end()}; 
    } 
*/ 
    cursor<false> begin_cursor() 
    { 
     return {ints_.begin()}; 
    } 
    cursor<false> end_cursor() 
    { 
     return {ints_.end()}; 
    } 
public: 
    MyRange() 
     : ints_{1, 2, 3, 4, 5, 6, 7} 
    {} 
}; 

int main() { 
    MyRange nc; 
    int& nci = *nc.begin(); // error here when const overloads present. 
} 

Full code here.

Bu birlikte çalışıyor: Bir örnek olarak, ben (sadece const erişim sağlar varsayılan olarak) const olmayan erişime izin vermek için (test/view_facade.cpp cinsinden) view_facade testini modifiye çalıştı begin_cursor ve end_cursor dosyasının const aşırı yüklediği yorumlandı.

error: binding 'const int' to reference of type 'int&' discards qualifiers 

Bana bir const yineleyici vererek const versiyonunu seçerek gibi görünüyor: Geri bu aşırı yükleri eklemek Ancak, aşağıdaki hata belirtilen hat (GCC 5.1) üzerinde oluşturulur. İstediğim: const nesneleri için const yineleyicileri ve const olmayan nesneler için const olmayan yineleyiciler. Bunu nasıl başarabilirim?

cevap

9

view_facade yapı görünümleri içindir. Görünümler, sahip olmadıkları verilere işaret eder. Onlar mantıksal olarak, onlar dolaylılar gibidirler. Ve işaretçiler gibi, üst düzey const, başvurulan verilerin const -ness'i üzerinde hiçbir etkiye sahip olmamalıdır. Bu bir int* veya bir int*const dereferans olup olmadığıdır, sonuç aynı: int&.

Görüşünüz bir görünüm değil. Verileri var. (Bkz. vector<int> ints_ veri üyesi.) Bu veri yapısını bir görünüme dönüştürmek için view_facade kullanmayı denemek, hayal kırıklığına yol açacaktır. Bu tasarım gereği çok fazla. Görünümler kapsayıcılardan farklıdır. Range-v3 kitaplığı bir kap kaplamasıyla gelmiyor, üzgünüm. Neler oluyor

(:... cursor_begin() const varsa görüşlerini indirection temsil beri çok sert view_facade çalışır const olmayan const begin() yapmak ve aynı tür iade end(), o hep seçilen her zaman bu olduğunu kodları koyar, genellikle bu kodlar kapsayıcı görünümleri ile kafa karıştırıcıdır.)

+0

Verilerinin sahibi olmayan bir görünümün ne anlama geldiğini anlamadım. Gönderdiğim örnek hemen hemen testlerden çıktı, ancak aslında yapmaya çalıştığım şey, menzil benzeri bir arayüzde bir işaretçiyi + boyuta sarmaktı. Görünüm, veriyi ayırma/boşaltma anlamında işaretçiye sahip olamayacağından (bir üçüncü taraf kitaplığı tarafından yönetiliyor), bir view_facade'nin uygun olduğunu düşündüm. Ama senin açıklaman mantıklı. Cevabınız için teşekkürler. – edflanders

+2

İşaretçi/uzunluk çifti * bir görünümdür. 'view :: sayıldı' tam olarak budur. Eğer 'vector' üyenizi işaretçi/uzunluk ile değiştirirseniz, işler daha iyi çalışmalıdır. –

+0

Ah! 'view :: sayıldı' mükemmel bir örnektir. Nasıl kaçırdığımı bilmiyorum. – edflanders

İlgili konular