Значение параметра шаблона класса по умолчанию

#c

#c

Вопрос:

Существует определение time_point шаблона класса для класса template из стандартной библиотеки C :

 template<
    class Clock,
    class Duration = typename Clock::duration
> class time_point;
 

Может кто-нибудь, пожалуйста, объясните мне строку:

 class Duration = typename Clock::duration
 

?
Я знаю, что мы определяем значение по умолчанию для второго параметра шаблона Duration , но чего я не понимаю, так это ::duration части после Clock имени типа. Разве это не должно быть просто:

 class Duration = typename Clock
 

?

Комментарии:

1. Clock::duration выглядит как класс-член. В C вы можете встраивать классы внутри классов. Это широко используется в контейнерах stl, просто проверьте ссылку на std::vector .

Ответ №1:

При этом будет использоваться тип Clock :

 class Duration = typename Clock
 

Однако Duration это тип, отличный от Clock . Существует именованное требование Clock. Среди прочего, он указывает, что часы должны иметь псевдоним duration члена.

Псевдоним участника выглядит примерно так:

  struct my_clock {
      using duration = int;
 };
 

Поэтому, когда вы создаете экземпляр a time_point<my_clock> , второй параметр шаблона становится my_clock::duration . Ключевое typename слово необходимо, поскольку оно является зависимым именем. Вам нужно убедиться, что компилятор Clock::duration действительно является типом.

Ответ №2:

Марек уже объяснил почти все в своем ответе, этот должен улучшить его.

typename необходимо сообщить компилятору «посмотрите, длительность вложена Clock и зависит от нее, сначала вы должны разрешить Clock , а затем вывести Clock::duration »

здесь есть глупый пример зависимого типа, не предназначенный для использования в производственном коде.

 template<typename T>
class MyBase
{
public:
   using UnderlyingType = T;
   // ...
   double foo() { return 5.5; }
};

class MyIntChild : public MyBase<int>{};

class MyDoubleChild : public MyBase<double>{};

template<typename T, typename D = typename T::UnderlyingType>
D makeFoo(Tamp; t)
{
   return t.foo();
}

MyIntChild a;
makeFoo<MyIntChild>(); // return 5 because return type is int;
 

Комментарии:

1. Где я могу найти using alias = type_name документацию по синтаксису? Официальная ссылка на сайт C не содержит никакой информации об использовании оператора «=» в объявлении using…

2. @Daros911 en.cppreference.com/w/cpp/language/type_alias

Ответ №3:

Это называется зависимым типом.

Обратите внимание, что класс может содержать typedef ( using = ) внутри. Clock::duration просто ссылается на это определение типа, которое ожидается внутри типа, переданного в качестве первого аргумента.

Теперь typename необходимо объяснить компилятору, что зависимый символ должен быть типом (он может быть постоянным).

Взгляните на некоторую документацию по часам, которая у него есть typedef для продолжительности:

std::хронограф::system_clock — cppreference.com

Типы членов

Тип участника Определение
rep знаковый арифметический тип, представляющий количество тиков в длительности часов
period тип std::ratio, представляющий тиковый период часов в секундах
duration std::chrono::длительность <повторение, период>, способный представлять отрицательные длительности
time_point std::chrono::time_point<std::chrono::system_clock>

Комментарии:

1. Где я могу найти using alias = type_name документацию по синтаксису? Официальная ссылка на сайт C не содержит никакой информации об использовании оператора «=» в объявлении using…

2. typedef int value_type и using value_type = int эквивалентны. С тех пор доступен второй C 11 .