Как я могу "переопределить" [], чтобы принять два аргумента в С++?

Я пытаюсь создать класс бит-вектора в С++ для моделирования некоторого оборудования. В большинстве HDL (аппаратных описаниях langauges), которые я знаю, конкретные биты ссылаются следующим образом:

my_vector[bit_position]

и под-векторы ссылаются так:

my_vector[msb:lsb]

или

my_vector[msb,lsb]

Я хочу иметь возможность сделать что-то подобное с моим классом бит-вектора. Есть ли способ сообщить operator[] принять два аргумента?

Альтернативы, которые я рассмотрел, следующие:

  • с помощью метода range:

    my_vector.range(msb,lsb)

  • используя строку и разбор ее:

    my_vector["msb:lsb"]

Но ни один из них не привлекателен. Во-первых, потому что он слишком отличается от того, как он моделируется в 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