Переместить конструктор или скопировать поведение конструктора в классе без переменных-членов

#c #templates #move-semantics

#c #шаблоны #переместить-семантика

Вопрос:

 class NullTimer {
 public:
  inline static bool changePeriod (const size_t) { return false; }
  inline static void dispose (void) {}
  inline static bool isActive (void) { return false; }
  inline static void reset (void) {}
  inline static void start (void) {}
  inline static void stop (void) {}
};

template <
  Timer
>
class Foo {
 public:
  Foo (
    const Timer amp; t
  ) :
    _t(t)
  {}

  Foo (
    Timer amp;amp; t
  ) :
    _t(t)
  {}
 private:
  Timer t;
};

Foo<NullTimer> bar(NullTimer());
  

Использование конструктора перемещения шаблонного типа вызывает странное поведение в моем встроенном приложении (трудно диагностируемое из-за встроенного характера). Если я делаю это в два этапа (используя конструктор копирования), то он ведет себя так, как ожидалось.

 NullTimer nt;
Foo<NullTimer> bar(nt);
  

Может ли кто-нибудь объяснить фундаментальные различия в механизме конструкторов и почему это может привести к другому поведению?

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

1. Старый добрый, самый неприятный синтаксический анализ.

2. Действительно, самое неприятное…

Ответ №1:

Foo<NullTimer> bar(NullTimer()); это объявление функции; оно объявляет функцию с именем, bar которая возвращает Foo<NullTimer> , и имеет неназванный параметр, который является указателем функции, возвращающим NullTimer и ничего не принимающим.

Вы можете изменить его на

 // since C  11
Foo<NullTimer> bar(NullTimer{});
Foo<NullTimer> bar{NullTimer()};
Foo<NullTimer> bar{NullTimer{}};

// before C  11
Foo<NullTimer> bar((NullTimer()));
  

Смотрите Самый неприятный синтаксический анализ

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

1. Foo<NullTimer> bar((NullTimer())) также работает, хотя я думаю, что формы с фигурными скобками следует предпочесть по соображениям удобочитаемости.

2. @Brian Да, это общее решение до C 11.