То, что делает “оператор =, должно быть нестатическим участником”, средним?

Следующее решение не идеально, но я все еще думаю, что стоит поделиться с вами. Я адаптировал ее из к этой более или менее похожей проблеме, хотя проблема линкования немного отличается. Как видите, выравнивание не идеальное. Возможно, вам придется немного подправить его. Мне пришлось удалить title_fontsize из plt.legend(), так как кажется, что он не совместим с matplotlib 2.2.2.

matplotlib.rcParams['text.usetex'] = True
matplotlib.rcParams['text.latex.preview'] = True

# Plot legend
legend_labels = [r'$\quad \quad \quad  \textsc{Prev.} < %i\%% 

enter image description here

% (15), r'$%i\%% \leq \textsc{Prev.} < %i\%%

enter image description here

% (15, 25), r'$%i\%% \leq \textsc{Prev.} < %i\%%

enter image description here

% (25, 35), r'$%i\%% \leq \textsc{Prev.} < %i\%%

enter image description here

% (35, 45), r'$%i\%% \leq \textsc{Prev.}

enter image description here

% (45)]

enter image description here

23
задан Cam 19 February 2012 в 22:48
поделиться

4 ответа

Именно то, что сказано: перегрузки операторов с 1 параметром должны быть функциями-членами. (объявлено внутри класса)

template<class T>
void list<T>::operator=(const list<T>& rhs)
{
    ...
}

Также, вероятно, будет хорошей идеей вернуть LHS из =, чтобы вы могли связать ее (например, a = b = c) - так что сделайте это list<T>& list<T>::operator=....

21
ответ дан 29 November 2019 в 01:52
поделиться

Если вы перегружаете оператор как функцию-член, вам следует использовать этот шаблон:

class A {
  A& operator=(const A& other) {
    if (this != &other) {
      ...
    }
    return *this;
  }
}

Три вещи, на которые следует обратить внимание:

  1. Проверка на самостоятельное назначение с назначением оператор (как выше);
  2. Аргумент должен быть константной ссылкой; и
  3. Возвращать результат операции как неконстантную ссылку, где вы возвращаете * this, чтобы разрешить цепочку операторов.

Вы также можете перегрузить оператор, внешний по отношению к классу. Это не относится к этому примеру, потому что вы не можете сделать это с помощью оператора присваивания, но стоит отметить, что во многих случаях он превосходит функции-члены. Типичная форма:

class A {
  friend const A& operator+(const A& a, const A& b);
  ...
}
const A& operator+(const A& a, const A& b) {
  A& ret = ...
  return ret;
}

Эта возвращает константную ссылку, поэтому вы не можете сделать это:

(a + b) = c
6
ответ дан 29 November 2019 в 01:52
поделиться

Из стандарта C ++, «Бинарные операторы»:

«Бинарный оператор должен быть реализован либо с помощью нестатической функции-члена с одним параметром, либо с помощью функции, не являющейся членом, с двумя параметрами. "

Он хочет, чтобы вы определили это в классе как член или сделали его статическим методом (в этом случае он должен принимать два параметра (как для lval, так и для rval).

-1
ответ дан 29 November 2019 в 01:52
поделиться

Поместите этот оператор в определение вашего класса. Он должен быть членом, потому что operator = является особенным, и вы все равно ничего не получите, написав его как нечлен. Оператор, не являющийся членом, имеет два важных преимущества:

  • Неявное преобразование правой и левой части вызова оператора
  • Нет необходимости знать о внутреннем устройстве класса. Функция может быть реализована как не член, не являющийся другом.

Для operator = оба неприменимы. Назначение временного результата преобразования не имеет смысла, и operator = в большинстве случаев потребует доступа к внутренним компонентам. Кроме того, специальный operator = автоматически предоставляется C ++, если вы не t предоставить один (так называемый оператор копирования-присваивания). Предоставление возможности перегрузить operator = в качестве не-члена внесло бы дополнительную сложность, очевидно, без практической выгоды, и поэтому это недопустимо.

Итак, измените свой код так, чтобы он выглядел так (предполагается, что operator = является не оператором копирования-присваивания, но присваивается из списка на что-то другое. Это не ясно из вашего вопроса):

class MyClass {
...
    template<class T>
    MyClass& operator=(const list<T>& lst)
    {
        clear();
        copy(lst);
        return *this;
    }
...
};

Довольно стандартно, что operator = снова возвращает ссылку на себя. Я рекомендую вам придерживаться этой практики. Программистам он покажется знакомым и может вызвать сюрпризы, если внезапно вернет void .

Предоставление возможности перегрузить operator = в качестве не-члена внесло бы дополнительную сложность, очевидно, без практической выгоды, и поэтому это недопустимо.

Итак, измените свой код так, чтобы он выглядел так (предполагается, что operator = является не оператором копирования-присваивания, но присваивается из списка на что-то другое. Это не ясно из вашего вопроса):

class MyClass {
...
    template<class T>
    MyClass& operator=(const list<T>& lst)
    {
        clear();
        copy(lst);
        return *this;
    }
...
};

Довольно стандартно, что operator = снова возвращает ссылку на себя. Я рекомендую вам придерживаться этой практики. Программистам он покажется знакомым и может вызвать сюрпризы, если внезапно вернет void .

Предоставление возможности перегрузить operator = в качестве не-члена внесло бы дополнительную сложность, очевидно, без практической выгоды, и поэтому это недопустимо.

Итак, измените свой код так, чтобы он выглядел так (предполагается, что operator = является не оператором копирования-присваивания, но присваивается из списка на что-то другое. Это не ясно из вашего вопроса):

class MyClass {
...
    template<class T>
    MyClass& operator=(const list<T>& lst)
    {
        clear();
        copy(lst);
        return *this;
    }
...
};

Довольно стандартно, что operator = снова возвращает ссылку на себя. Я рекомендую вам придерживаться этой практики. Программистам он покажется знакомым и может вызвать сюрпризы, если внезапно вернет void .

т разрешено.

Итак, измените свой код так, чтобы он выглядел так (предполагается, что operator = является не оператором копирования-присваивания, но присваивается из списка на что-то другое. Это не ясно из вашего вопроса):

class MyClass {
...
    template<class T>
    MyClass& operator=(const list<T>& lst)
    {
        clear();
        copy(lst);
        return *this;
    }
...
};

Довольно стандартно, что operator = снова возвращает ссылку на себя. Я рекомендую вам придерживаться этой практики. Программистам он покажется знакомым и может вызвать сюрпризы, если внезапно вернет void .

т разрешено.

Итак, измените свой код так, чтобы он выглядел так (предполагается, что operator = является не оператором копирования-присваивания, но присваивается из списка на что-то другое. Это не ясно из вашего вопроса):

class MyClass {
...
    template<class T>
    MyClass& operator=(const list<T>& lst)
    {
        clear();
        copy(lst);
        return *this;
    }
...
};

Довольно стандартно, что operator = снова возвращает ссылку на себя. Я рекомендую вам придерживаться этой практики. Программистам он покажется знакомым и может вызвать сюрпризы, если внезапно вернет void .

Довольно стандартно, что operator = снова возвращает ссылку на себя. Я рекомендую вам придерживаться этой практики. Программистам он покажется знакомым и может вызвать сюрпризы, если внезапно вернет void .

Довольно стандартно, что operator = снова возвращает ссылку на себя. Я рекомендую вам придерживаться этой практики. Программистам он покажется знакомым и может вызвать сюрпризы, если внезапно вернет void .

18
ответ дан 29 November 2019 в 01:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: