Поведение порядка в лексической области - PullRequest
0 голосов
/ 21 октября 2010

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

class C;

namespace Order1 {
  bool operator< (const C&, const C&);
}
namespace Order2 {
  bool operator< (const C&, const C&);
}

Операторы для >, <=, >= также определены, но это не главное.Теперь пользователь может сказать using namespace Order1; или ... Order2 в области видимости файла или блока и получить запрошенное поведение для остальной части этого файла / блока.

Неутешительная часть, которую я хотел бычтобы улучшить, если возможно, это то, что эти using s не могут быть вложенными.

void g(const C&, const C&);

using namespace Order1; // for most functions in this file

void f(const C& x, const C& y) {
  bool test1 = x < y; // Order1
  {
    // Would like to switch to Order2 for this block.
    using namespace Order2;
    bool test2 = x < y; // Ambiguous overload!

    g(x, y); // Unaffected by local using-s.
  }
}

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

Другая связанная с этим идея заключается в том, чтобы позволить фиктивным объектам в стеке, чьи конструкторы и деструкторы манипулируют «текущими настройками», для которых нужно использовать поведение.Но я не думаю, что хочу идти таким путем в этой ситуации, поскольку это означало бы, что эквивалент f выше может изменить поведение других функций, называемых как g.

Есть ли другой способполучить подобный эффект, но позволяя вложенным операциям с самым внутренним блоком «скрывать» остальные?Или я застрял с одним поведением перегруженных операторов на декларативный регион?Я полагаю, что это управляемо, так как код все еще может явно использовать функцию или функтор вместо использования операторов.

Ответы [ 3 ]

2 голосов
/ 21 октября 2010

Я бы придерживался обычных функций сравнения.Остальная часть кода будет чище.Нет using namespace... или явных вызовов в область operator<.Так легче читать, ИМО ...

int main() {
   bool b = compare1(4, 5);
   b = compare2(4, 5);
}
0 голосов
/ 21 октября 2010

Почему бы вам не очистить пространства имен и просто объявить две перегрузки operator < с разными типами аргументов, по одному для каждого типа класса?

UPDATE

Как указал dgnorton в комментарии ниже, у вас есть один класс с двумя различными порядками, определенными для него. Это кажется возможной причиной проблем. Можно ли разделить это на два разных класса?

0 голосов
/ 21 октября 2010

вместо использования пространства имен Order2 вставьте

bool test2 = Order2::operator<(x, y);

, который будет работать в этом случае.Если вы хотите «метапрограммировать», т.е. иметь возможность передавать в Order1 / Order2 в качестве параметра шаблона, вы должны создать их структуры (или классы) с помощью оператора

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...