Следующее решение не идеально, но я все еще думаю, что стоит поделиться с вами. Я адаптировал ее из к этой более или менее похожей проблеме, хотя проблема линкования немного отличается. Как видите, выравнивание не идеальное. Возможно, вам придется немного подправить его. Мне пришлось удалить 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\%% % (15),
r'$%i\%% \leq \textsc{Prev.} < %i\%% % (15, 25),
r'$%i\%% \leq \textsc{Prev.} < %i\%% % (25, 35),
r'$%i\%% \leq \textsc{Prev.} < %i\%% % (35, 45),
r'$%i\%% \leq \textsc{Prev.} % (45)]
Именно то, что сказано: перегрузки операторов с 1 параметром должны быть функциями-членами. (объявлено внутри класса)
template<class T>
void list<T>::operator=(const list<T>& rhs)
{
...
}
Также, вероятно, будет хорошей идеей вернуть LHS из =, чтобы вы могли связать ее (например, a = b = c
) - так что сделайте это list<T>& list<T>::operator=....
Если вы перегружаете оператор как функцию-член, вам следует использовать этот шаблон:
class A {
A& operator=(const A& other) {
if (this != &other) {
...
}
return *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
Из стандарта C ++, «Бинарные операторы»:
«Бинарный оператор должен быть реализован либо с помощью нестатической функции-члена с одним параметром, либо с помощью функции, не являющейся членом, с двумя параметрами. "
Он хочет, чтобы вы определили это в классе как член или сделали его статическим методом (в этом случае он должен принимать два параметра (как для lval, так и для rval).
Поместите этот оператор в определение вашего класса. Он должен быть членом, потому что 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
.