Гипотетические, ранее-C ++ 0x концепции вопросов - PullRequest
12 голосов
/ 30 июля 2009

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

После прочтения некоторых вводных материалов о концепциях, предложенных C ++ 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;
    }
} 

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

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

1 Ответ

11 голосов
/ 30 июля 2009

Я использовал самый последний черновик C ++ 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) Аксиомы были слабым местом спецификации, и они постоянно обновлялись, чтобы иметь некоторый (более) смысл. Непосредственно перед тем, как концепции были извлечены из черновика, была бумага , которая немного изменилась - прочитайте ее и посмотрите, имеет ли она для вас больше смысла, или у вас все еще есть вопросы по этому поводу.

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

...