Что эквивалентно броску для понятий?

Рассмотрим class A удовлетворяет двум понятиям ConceptA а также ConceptB, Пусть функция foo перегружен для двух понятий:

void foo(ConceptA& arg);
void foo(ConceptB& arg);
A a;
fun(concept_cast<ConceptA>(a));

Примечание. В этом примере используется синтаксис «краткая запись», предложенный как часть N3701, § 5

Есть ли что-то вроде concept_cast который позволяет пользователям выбирать перегрузку?

Например:
Допустим
ConceptA говорит, что T должен иметь функцию-член bar()
ConceptB говорит, что T должен иметь функцию-член baz()
а также class A имеет оба bar() а также baz() функция-член

Это явно неоднозначно, но есть ли способ явно выбрать, как у нас static_cast для нормальных перегрузок?

Обновить: Принято, ответ более 2 лет. Любое обновление в C ++ 17?

19

Решение

Если одна из концепций является более ограниченной версией другой (например, все, что удовлетворяет ConceptA также удовлетворит ConceptB но не наоборот), то самая ограниченная перегрузка, которая A удовлетворяет будет выбран.

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

относительно concept_castЯ не думаю, что есть что-то подобное в текущем предложении. По крайней мере, не во время встречи в Бристоле (апрель 13 года). Я не ожидаю, что это изменится, поскольку в настоящее время, как представляется, основное внимание уделяется обеспечению того, чтобы ядро ​​предложения о концептуальных условиях / ограничениях было работоспособным и приемлемым для комитета.

Вероятно, будет некоторый спрос на явный выбор перегруженных шаблонных функций, подобных этому, и, возможно, такое приведение правильное, но я не уверен. Считайте, что такой бросок будет только быть полезным для устранения неоднозначности перегрузки, где, как static_cast это более общая особенность. Результат concept_cast будет таким же, как исходное значение вне контекста разрешения перегрузки!

Редактировать: Смотря на последнее предложение (N3701), не существует явного указания, какую функцию шаблона создавать.

4

Другие решения

Вы утверждаете, что static_cast может использоваться для явного выбора «нормальной» перегрузки. На сегодняшнем C ++ можно написать следующее:

template<typename P, EnableIf<NullablePointer<P>>...>
void foo(P&);

template<typename It, EnableIf<Iterator<It>>...>
void foo(It&);

При условии, что NullablePointer а также Iterator выполнить проверку концепции для связанных Стандартных концепций, затем int* q; foo(q); не имеет никакой надежды на компиляцию, потому что int* это модель NullablePointer и из Iterator (и ни одна концепция не относится к другой). Там нет ничего очевидного для static_cast чтобы помочь в этой ситуации.

Мой пример (что вы можете проверить для себя) чрезвычайно важен, потому что этот тип кода является тем, что Concepts Lite пытается формализовать. Представляемый вами набор перегрузки эквивалентен:

template<typename A>
requires ConceptA<A>
void foo(A& arg);

template<typename B>
requires ConceptB<B>
void foo(B& arg);

Обратите внимание на сходство между requires пункты и тому EnableIf «статьи».

1

По вопросам рекламы [email protected]