2013-11-27 3 views
0

У меня есть класс Foo, который инкапсулирует доступ к вектору и обеспечивает доступ к нему через оператора индексного:Как упростить использование перегруженного оператора индекса с помощью указателя?

typedef int* IntPtr; 

class Foo { 
    std::vector<IntPtr> bars; 
    IntPtr& operator[](size_t idx) { 
     return bars[idx]; 
    } 
}; 

В классе Bar я хочу использовать Foo. Хотя решение 1 работает, это довольно неудобно. Я предпочел бы что-то подобное решение 2. Очевидно, что вызов метода (даже если он возвращает именующее выражение) не может быть назначено что-то, хотя вызов метода больше ничего не делать, чем решение 1.

class Bar { 
    Foo *foo; //some initialization 

    IntPtr helper(size_t idx) { 
     return (*foo)[idx]; 
    } 

    void barfoo() { 
     size_t baz = 1; 
     IntPtr qux; 

     //solution 1 
     qux = (*foo)[baz]; //works 
     (*foo)[baz] = &1; //works 

     //solution 2 
     qux = helper(baz); //works 
     helper(baz) = &1; //does not work: "expression is not assignable" 
    }  
}; 

Вопрос: Как я могу упростить использование перегруженного оператора индекса?

РЕДАКТИРОВАТЬ: Измененный используемый тип, чтобы от int к int*. Извините, я прищурился при создании примера.

Я предполагаю, что проблема связана с извращенным int*&.

+1

[Работы для меня] (http://ideone.com/cIfszt) (как только я исправить доступность 'Foo :: оператор []'). Вы, безусловно, можете назначить ссылку * lvalue *, возвращаемую функцией. Вы уверены, что ошибка исходит из этого кода? –

+0

если хелпер возвращает ссылку на ваше решение 2 работает – Drax

+0

Какой компилятор вы используете? Потому что эта строка должна работать ... – cmaster

ответ

1

Лучший способ - написать обычный метод, например Foo::at(size_t idx), обеспечивая ту же функциональность, что и ваш оператор. Обратите внимание, что STL делает то же самое (просто взгляните на std::vector). Затем вы можете просто позвонить foo->at(baz);. Чтобы избежать rendundancy вы можете изменить реализацию operator[]:

int& operator[](size_t idx) { 
    return at(idx); 
} 

В вашем фрагменте кода, вы не можете присвоить значение для возвращения, потому что вы забыли вернуть ссылку.

Не так хорошо, но альтернативой будет foo->operator[](baz);, хотя я решительно отговариваю вас написать такой уродливый код.

+0

Даже тогда 'foo-> at (baz) = 1' было бы невозможно. – mort

+0

@mort Почему бы и нет? Должен быть. – BoBTFish

+0

Э? Почему нет? 'at' - обычный метод, вы можете назвать его так же, как и любой другой метод. Вы вызываете метод из указателя с помощью оператора '->'. – Paranaix

0

Darn. Я просто забыл, чтобы helper вернуть значение с помощью ссылки:

IntPtr& helper(size_t idx) 

или

int*& helper(size_t idx) 
Смежные вопросы