Автоматическая генерация const-перегрузки для функции-члена

Я пытаюсь реализовать семантику ключевого слова D-языка inout в С++ (просто для удовольствия).

В зависимости от контекста он, по сути, говорит одну из двух вещей:

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

Полезно при написании функций-членов, таких как begin и end, среди других случаев.

Мне удалось создать корректную реализацию первого случая с относительной легкостью (хотя интерфейс уверен, что это не так): http://ideone.com/wgaDJJ

Вторая, однако, кажется невозможной, по моему лучшему предположению. Насколько мне известно, вы можете получить такую ​​ "автоматическую генерацию перегрузки по перестройке" при использовании шаблонов, но вы не можете создавать шаблоны по аргументу "this". В частности, вы заметите, что этот код не работает/компилируется: http://ideone.com/W4fTa4

Интересно:

  • Я что-то пропустил? Возможно ли реализовать второй случай, не прибегая к макросам или дублированию кода?
  • Кто-нибудь знает, есть ли предложение по стандартам WG21 по этому вопросу? (не обязательно inout, просто что-нибудь на тему)
  • Что такое отраслевой стандарт для решения этой проблемы? (Здесь, возможно, не такой ужасный вариант, с которым я играл: http://ideone.com/PW0vK4)

Ответ 1

Краткие ответы

  • Нет и нет.
  • Справедливо связанное: дополнительные опции для перегрузки методов будут иметься с Concepts Light.
  • Внесите две перегрузки метода, один const и один не const (по существу, ваш последний пример).

Подробнее

Что вы хотите достичь в пункте 2

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

является вариацией более общего:

Сделайте что-то другое в этом методе в зависимости от константы экземпляра, на который вы его называете.

Единственный способ сделать это на С++ - это иметь две перегрузки метода, которые отличаются только своей константой. Поскольку тип this должен быть статически известен, вы не можете написать один метод, который работает с двумя разными типами для this. Даже с помощью шаблонных методов вы должны явно писать (или опускать) модификатор const, поскольку нет возможности автоматически генерировать другой экземпляр шаблона, основанный только на константе this. Вам нужно "экпортировать" this в некотором роде, если вы хотите написать единый шаблонный метод. По существу, что вы сделали в своем последнем примере.

Что касается отраслевого стандарта, вам нужно только посмотреть на стандартную библиотеку. Все контейнеры, например, имеют перегрузки методов для методов begin()/end(), которые отличаются только константой, в частности, для реализации требуемой функции. (например: http://en.cppreference.com/w/cpp/container/vector/begin)

Насколько я знаю, нет конкретного предложения реализовать аналогичную функцию в следующем стандарте. Когда дело доходит до перегрузки, одним большим новым дополнением, которое может быть связано с С++ 17, является Concepts Light, который добавляет новые способы перегрузки методов, основанных на концепциях. См. Некоторые презентации/видео Эндрю Саттона по этой теме (например: https://www.youtube.com/watch?v=NZeTAnW5LL0, около 50-минутной отметки, хотя вы можете захотеть посмотрите все на фоне:)