Идентичность выражений

AR Hovsepyan

template < class Tp, class C = std::list<tp>, size_t Tag = 5 >
class accountant {};

class  D1 : accountant<******> {};
class  D2 : accountant<******, void,="" void=""> {};
</******,></******></tp>

Хотелось бы узнать как будут отличаться производные классы, если эти два выражения не идентичны? Или все таки они идентичны?..

По причине того, что я неправильно задал интересующий мне вопрос, добавлю ниже

класс D2 не компилируется, а вот это:

class It : public std::iterator<std::random_access_iterator_tag, int,="" void,="" void="">{};
</std::random_access_iterator_tag,>

компилируется. И вот это тоже:

class It : public std::iterator<std::random_access_iterator_tag, int=""> {};
</std::random_access_iterator_tag,>

В чем причина? И в чем разница между первым определением класса It и вторым?

1 ответ

AR Hovsepyan

Хотелось бы понять, как вы собираетесь скомпилировать

class  D2 : accountant<******, void,="" void=""> {};
</******,>

подставляя void вместо значения? :)

Но в любом случае они будут различны. Как будут различны классы

class D1: public Base {};
class D2: public Base {};

А вот, скажем,

accountant

и

accountant<******,std::list<******>,5>
</******,std::list<******>

эти будут идентичными.

Update

Вот как iterator определен в VC++2017:

template<class _category,="" class="" _ty,="" _diff="ptrdiff_t," _pointer="_Ty" *,="" _reference="_Ty&">
    struct _CXX17_DEPRECATE_ITERATOR_BASE_CLASS iterator
    {   // base type for iterator classes
    using iterator_category = _Category;
    using value_type = _Ty;
    using difference_type = _Diff;
    using pointer = _Pointer;
    using reference = _Reference;
    };
</class>

Видно, что три последние параметра шаблона - просто типы, со значениями по умолчанию. void - тоже просто тип... так что его можно использовать в качестве аргументов шаблона. Если не использовать ничего - то этими типами в вашем варианте (для int) будут ptrdiff_t, int* и int&.

Оба варианта компилируются - пока вы не попытаетесь использовать, скажем, псевдоним pointer для определения переменной или что-нибудь в этом роде, где void использовать категорически нельзя.

licensed under cc by-sa 3.0 with attribution.