Рассмотрим 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?
Если одна из концепций является более ограниченной версией другой (например, все, что удовлетворяет ConceptA
также удовлетворит ConceptB
но не наоборот), то самая ограниченная перегрузка, которая A
удовлетворяет будет выбран.
Если ни одна из концепций не является более ограниченной, чем другая, то считается, что эти две концепции являются неоднозначными перегрузками. Учитывая, как вы сформулировали вопрос, я полагаю, вы уже знали это.
относительно concept_cast
Я не думаю, что есть что-то подобное в текущем предложении. По крайней мере, не во время встречи в Бристоле (апрель 13 года). Я не ожидаю, что это изменится, поскольку в настоящее время, как представляется, основное внимание уделяется обеспечению того, чтобы ядро предложения о концептуальных условиях / ограничениях было работоспособным и приемлемым для комитета.
Вероятно, будет некоторый спрос на явный выбор перегруженных шаблонных функций, подобных этому, и, возможно, такое приведение правильное, но я не уверен. Считайте, что такой бросок будет только быть полезным для устранения неоднозначности перегрузки, где, как static_cast
это более общая особенность. Результат concept_cast
будет таким же, как исходное значение вне контекста разрешения перегрузки!
Редактировать: Смотря на последнее предложение (N3701), не существует явного указания, какую функцию шаблона создавать.
Вы утверждаете, что 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
«статьи».