Как я могу "переопределить" [], чтобы принять два аргумента в С++?
Я пытаюсь создать класс бит-вектора в С++ для моделирования некоторого оборудования. В большинстве HDL (аппаратных описаниях langauges), которые я знаю, конкретные биты ссылаются следующим образом:
my_vector[bit_position]
и под-векторы ссылаются так:
my_vector[msb:lsb]
или
my_vector[msb,lsb]
Я хочу иметь возможность сделать что-то подобное с моим классом бит-вектора. Есть ли способ сообщить operator[]
принять два аргумента?
Альтернативы, которые я рассмотрел, следующие:
Но ни один из них не привлекателен. Во-первых, потому что он слишком отличается от того, как он моделируется в HDL, второй, потому что мне не нравится иметь дело со строками, когда мне это не нужно, и это кажется неэлегантным.
Какой лучший способ сделать это?
Ответы
Ответ 1
Проблема:
Помимо operator()
все операторы имеют фиксированную arity, что фактически исключает любое изменение
Затем у вас есть несколько решений:
- перегрузка
operator()
вместо: vector(msb, lsb)
- используйте два последовательных вызова:
vector[msb][lsb]
- перегрузить оператор запятой:
vector[msb,lsb]
Последнее решение соответствует требуемому синтаксису, но несколько тонко:
- сначала вам нужно либо
msb
, либо lsb
иметь нестандартный тип (для операторов нельзя перегружать только встроенные)
- вы затем обеспечиваете перегрузку
operator,
для этого типа, возвращая объект Range
- вы, наконец, предоставляете пользовательский
operator[](Range)
в своем классе
Настоящий обрыв - это первая точка: один из msb
или lsb
должен иметь нестандартный тип. Это можно несколько облегчить, используя Boost.StrongTypedef
, который создает настраиваемый тип, который имитирует существующий.
Ответ 2
простая структура с двумя членами в качестве параметра для оператора []...
struct pos
{
int lsb;
int msb;
};
pos foo={1,2};
my_vector[foo];
или в новом стандарте, я считаю, что вы можете просто сделать:
my_vector[pos{1,2}]
Ответ 3
Есть ли способ сказать operator[]
принять два аргумента?
Нет.
Существуют две общие альтернативы. Один из них - перегрузить operator()
. Затем вам необходимо вызвать его с помощью синтаксиса ()
.
Другой должен иметь operator[]
вернуть прокси-объект, для которого также перегружен operator[]
. Это может быть вызвано, как многомерные массивы в C, с несколькими [][]
последовательно.
Ответ 4
Обычное решение - переопределить оператор(). Это позволяет делать такие вещи, как my_vector (1, 2).
Возможны работы с использованием оператора [], но, как указывает Маттиу М., вам нужен специальный тип, который должен быть задействован.
Ответ 5
В С++ невозможно использовать два аргумента operator []. Имена, приоритет, ассоциативность и арность операторов фиксируются языком. 1 Operator() однако может принимать два аргумента...
Ответ 6
использовать язык с массивами? = P