Infinite Recursion in Meta Integer Square Root

瘦欲@ 提交于 2019-12-05 06:54:48

Template evaluation isn't lazy by default.

static const std::size_t square_root = 
    sq <= value ?
    isqrt_impl<value, sq+dlt, dlt+2>::square_root :
    (dlt >> 1) - 1;

will always instantiate the template, no matter what the condition. You need boost::mpl::eval_if or something equivalent to get that solution to work.

Alternatively you can have a base case partial template specialization that stops the recursion if the condition is met, like in K-ballos answer.

I'd actually prefer code that uses some form of lazy evaluation over partial specialization because I feel it is easier to comprehend and keeps the noise that comes with templates lower.

Unfortunately, this is causing infinite recursion (on GCC 4.6.1) and I am unable to figure out what is wrong with the code.

I don't see a base case specialization for isqrt_impl. You need to have a template specialization for the base case to break this recursion. Here is a simple attempt at that:

template <std::size_t value, std::size_t sq, std::size_t dlt, bool less_or_equal = sq <= value >
struct isqrt_impl;

template <std::size_t value, std::size_t sq, std::size_t dlt>
struct isqrt_impl< value, sq, dlt, true >{
    static const std::size_t square_root = 
        isqrt_impl<value, sq+dlt, dlt+2>::square_root;
};

template <std::size_t value, std::size_t sq, std::size_t dlt>
struct isqrt_impl< value, sq, dlt, false >{
    static const std::size_t square_root = 
        (dlt >> 1) - 1;
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!