Подтвердить что ты не робот

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

Рассмотрим a 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 лет. Любое обновление в С++ 17?

4b9b3361

Ответ 1

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

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

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

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

Изменить: Рассматривая последнее предложение (N3701), не предусмотрено явно указывать, какой шаблон для создания экземпляра.

Ответ 2

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

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.