Информация об изменениях

Сообщение Re[3]: Мета-рекурсия от 03.08.2015 16:32

Изменено 03.08.2015 16:59 watchmaker

Здравствуйте, LaptevVV, Вы писали:

LVV>Ну так, может быть, просто разные компилеры используются?


Конечно разные. Но смысл не в том, что они разные, а в том, что результат шаблона из первого сообщения неопределён. И поэтому такой код не нужно писать или использовать. То что разные компиляторы выдают разные ответы — лишь следствие проблемы в исходном тексте.
Re[3]: Мета-рекурсия
Здравствуйте, LaptevVV, Вы писали:

LVV>Ну так, может быть, просто разные компилеры используются?


Конечно разные. Но смысл не в том, что они разные, а в том, что результат шаблона из первого сообщения неопределён. И поэтому такой код не нужно писать или использовать. То что разные компиляторы выдают разные ответы — лишь следствие проблемы в исходном тексте.


Ну и если уж разговор зашёл об компиляторах, то, например, gcc-5.2 компилирует исходный пример, а clang-3.7 выдаёт ошибку. С другой стороны, если пример чуть-чуть переписать пользуясь средствами только C++03, то ситуация может изменится на противоположную: gcc-5.2 теперь находит бесконечную рекурсию, а clang-3.7 выдаёт ответ. Так что тут даже нельзя утверждать что gcc или clang хуже другого справляются с таким кодом — оба иногда сообщают об ошибке (что хорошо), а иногда выдают численный ответ (что на самом деле хуже, так как может замаскировать ошибки в более сложных случаях).

Ну и если уж выбирать способ считать биты, то куда лучше вообще вместо шаблонов взять constexpr-функции — в них правила рекурсии другие, более интуитивно понятные и с ними всё работает во всех компиляторах, удовлетворяющих стандарту:
template <typename UInt>
constexpr unsigned BitsOf(UInt A = -1) {
    return A ? 1 + BitsOf(A >> 1) : 0;
}