Гипотетические вопросы о концепциях C ++ 0x

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

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

1) Будет ли тип, который поддерживает конкретную производную концепцию (неявно, с помощью ключевого слова auto или явно с помощью concept_maps), также должен поддерживать базовую концепцию независимо? Другими словами, включает ли процесс получения концепции из другого (например, concept B<typename T> : A<T>) неявно «невидимое» выражение requires (внутри 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? Или для концептов, включающих в себя имена типов, необходима карта-концепт-карта?

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

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

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

Что бы это сделало? Это вообще действительно?

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


person GRB    schedule 29.07.2009    source источник


Ответы (1)


Я использовал самый последний черновик 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), с целью правила языка «как если бы» (т. Е. Компилятору разрешено делать любые оптимизации, которые он хочет, при условии, что результат ведет себя так, как если бы их не было). Однако компилятор никоим образом не обязан проверять правильность аксиом (поэтому они и называются аксиомами!) - он просто принимает их такими, какие они есть.

person Pavel Minaev    schedule 29.07.2009
comment
Отличный ответ. Вы подтвердили мои подозрения по поводу вопросов 2) и 3), и я никогда не думал об 1) таким образом. Еще раз спасибо. - person GRB; 30.07.2009