2009-07-29 2 views
11

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

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

1) Может ли тип, поддерживающий определенную производную концепцию (либо неявно, с помощью ключевого слова auto, либо явно через concept_maps), также должен поддерживать базовую концепцию indepdendently? Другими словами, не подразумевает ли акт получения понятия от другого (например, 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; 
    } 
} 

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

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

ответ

10

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

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

+0

Отличный ответ. Вы подтвердили подозрения, которые у меня были о вопросах 2) и 3), и я никогда не думал об этом). Еще раз спасибо. – GRB