Почему компилятор не перестанет выдавать ошибки в этом коде шаблона - PullRequest
0 голосов
/ 22 мая 2018

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

template <typename STREAM, typename TUPLE, std::size_t INDEX> struct streamer {
  STREAM &operator()(STREAM &out, const TUPLE &tuple) {

    streamer<STREAM, TUPLE, INDEX - 1U> stream;
    return out << stream(out, tuple) << std::get<INDEX>(tuple);
  }
};

template <typename STREAM, typename TUPLE> struct streamer<0> {
  STREAM &operator()(STREAM &out, const TUPLE &tuple) {

    return out << std::get<INDEX>(tuple);
  }
};

template <typename STREAM, typename TUPLE>
STREAM &operator<<(STREAM &out, const TUPLE &tuple) {

  streamer<STREAM, TUPLE, std::tuple_size<TUPLE>::value - 1U> stream;
  return stream(out, tuple);
}

int main() {

  std::tuple<std::string, std::string> a_guy("name", "surname");
  std::cout << a_guy << std::endl;
  return 0;
}

Обратите внимание, что вопрос не в том, «как напечатать кортеж», поскольку их уже много.Вопрос в том, почему этот конкретный код не работает, и, в частности, почему он делает цикл компилятора вечным.

1 Ответ

0 голосов
/ 22 мая 2018

У вас есть синтаксические ошибки в вашей специализации, о чем вам говорит компилятор.Кроме того, в вашей специализации нет параметра с именем INDEX, что является еще одной ошибкой.Правильный синтаксис должен быть:

template <typename STREAM, typename TUPLE> struct streamer<STREAM, TUPLE, 0> {
//                                                         ^^^^^^  ^^^^^  
  STREAM &operator()(STREAM &out, const TUPLE &tuple) {

    return out << std::get<0>(tuple);
//                        ^^^
  }
};

Есть еще одна проблема с вашим кодом:

return out << stream(out, tuple) << std::get<INDEX>(tuple);

Это вызывает operator<<(std::ostream&, std::ostream&), который не существует, ноне нужно в любом случае.Просто используйте return stream(out, tuple) << std::get<INDEX>(tuple);.

...