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

Гипотетические, ранее вопросы С++ 0x

( Преамбула: Я поздний приверженец игры С++ 0x, и недавние споры относительно удаления понятий из стандарта С++ 0x побудили меня узнать больше о них. Хотя я понимаю, что все мои вопросы полностью гипотетические - поскольку понятия не будут действительными С++-кодом в течение некоторого времени, если вообще - мне все еще интересно узнать больше о концепциях, особенно учитывая, как это поможет я более подробно понимаю достоинства недавнего решения и противоречия, которые последовали за ним)

После ознакомления с некоторыми вводными материалами по концепциям, как предлагал их С++ 0x (до недавнего времени), у меня возникают проблемы, связанные с некоторыми синтаксическими проблемами. Без дальнейших церемоний, вот мои вопросы:

1) Будет ли тип, поддерживающий определенную производную концепцию (либо неявно, через ключевое слово auto, либо явно через concept_maps), также должен поддерживать базовую концепцию без изменений? Другими словами, подразумевается ли акт получения понятия от другого (например, concept B<typename T> : A<T>) включать "невидимый" запрос (внутри B, requires A<T>;)? Путаница возникает на странице Википедии по понятиям, которая гласит:

Как и в наследовании классов, типы, которые отвечают требованиям концепция также отвечает требованиям базовая концепция.

Похоже, что тип должен удовлетворять только производным концептуальным требованиям и необязательно базовым концептуальным требованиям, что не имеет для меня никакого смысла. Я понимаю, что Википедия далека от окончательного источника; является ли приведенное выше описание просто плохим выбором слов?

2) Может ли концепция, которая перечисляет имена типов, "авто"? Если да, то каким образом компилятор автоматически сопоставляет эти типы имен? Если нет, есть ли другие случаи, когда было бы неверно использовать "авто" в концепции?

Чтобы прояснить, рассмотрим следующий гипотетический код:

template<typename Type>
class Dummy {};

class Dummy2 { public: typedef int Type; };

auto concept SomeType<typename T>
{
     typename Type;
}

template<typename T> requires SomeType<T>
void function(T t)
{}

int main()
{
    function(Dummy<int>()); //would this match SomeType?
    function(Dummy2()); //how about this?
    return 0;
}

Будет ли любой из этих классов соответствовать SomeType? Или является понятием concept_map, необходимым для понятий с именами типов?

3) Наконец, я с трудом понимаю, какие аксиомы могут быть определены. Например, можно ли определить концепцию аксиомы, которая логически несовместима, например

concept SomeConcept<typename T>
{
    T operator*(T&, int);

    axiom Inconsistency(T a)
    {
         a * 1 == a * 2;
    }
} 

Что бы это сделало? Это даже верно?

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

4b9b3361

Ответ 1

Я использовал самый последний проект С++ 0x, N2914 (который по-прежнему содержит в себе концепцию) в качестве ссылки для следующего ответа.

1) Концепции в этом как интерфейсы. Если ваш тип поддерживает концепцию, он также должен поддерживать все "базовые" концепции. Заявление Википедии, которое вы цитируете, имеет смысл с точки зрения клиента типа - если он знает, что T удовлетворяет понятию Derived<T>, то он также знает, что он удовлетворяет понятию Base<T>. С точки зрения автора, это, естественно, означает, что оба они должны быть реализованы. См. 14.10.3/2.

2) Да, понятие с членами typename может быть auto. Такие члены могут автоматически выводиться, если они используются в определениях членов функции в одной и той же концепции. Например, value_type для итератора может быть выведен как возвращаемый тип его operator*. Однако, если член типа нигде не используется, он не будет выводиться и, следовательно, не будет определяться неявно. В вашем примере нет способа вывести SomeType<T>::Type для Dummy или Dummy1, поскольку Type не используется другими членами концепции, поэтому ни один класс не будет отображен в понятии (и, фактически, ни один класс не мог бы автоматически отобразить его). См. 14.10.1.2/11 и 14.10.2.2/4.

3) Аксиомы были слабой точкой спецификации, и они постоянно обновлялись, чтобы сделать некоторый (более) смысл. Незадолго до того, как концепции были вычеркнуты из черновика, был paper, который изменился совсем немного - прочитайте его и посмотрите, имеет ли смысл вы, или у вас все еще есть вопросы относительно этого.

В вашем конкретном примере (учитывая синтаксическую разницу) это означало бы, что компилятору было бы разрешено считать выражение (a*1) таким же, как (a*2), с целью правила "как-если" языка (т.е. компилятор разрешил делать любые оптимизации, которые он хочет, пока результат ведет себя так, как будто их не было). Однако компилятор никоим образом не обязан проверять правильность аксиом (поэтому их называют аксиомами!) - он просто берет их за то, что они есть.