Ngày tốt,Truy cập vô hạn trong Meta Integer Square Root
Một người bạn của tôi đang hỏi về việc chuyển một hàm số nguyên vuông thành một hàm meta. Dưới đây là những chức năng ban đầu:
unsigned isqrt(unsigned value)
{
unsigned sq = 1, dlt = 3;
while(sq<=value)
{
sq += dlt;
dlt += 2;
}
return (dlt>>1) - 1;
}
Tôi đã viết một phiên bản sử dụng meta constexpr
, nhưng ông nói rằng ông không thể sử dụng tính năng mới đối với một số lý do:
constexpr std::size_t isqrt_impl
(std::size_t sq, std::size_t dlt, std::size_t value){
return sq <= value ?
isqrt_impl(sq+dlt, dlt+2, value) : (dlt >> 1) - 1;
}
constexpr std::size_t isqrt(std::size_t value){
return isqrt_impl(1, 3, value);
}
Vì vậy, tôi nghĩ rằng nó không nên được rằng khó có thể thay đổi đó vào template struct mà gọi đó là tự đệ quy:
template <std::size_t value, std::size_t sq, std::size_t dlt>
struct isqrt_impl{
static const std::size_t square_root =
sq <= value ?
isqrt_impl<value, sq+dlt, dlt+2>::square_root :
(dlt >> 1) - 1;
};
template <std::size_t value>
struct isqrt{
static const std::size_t square_root =
isqrt_impl<value, 1, 3>::square_root;
};
Thật không may, điều này đang gây ra đệ quy vô hạn (trên GCC 4.6.1) và tôi không thể tìm ra những gì là sai w ith mã. Dưới đây là các lỗi:
C:\test>g++ -Wall test.cpp
test.cpp:6:119: error: template instantiation depth exceeds maximum of 1024 (use
-ftemplate-depth= to increase the maximum) instantiating 'struct isqrt_impl<25u
, 1048576u, 2049u>'
test.cpp:6:119: recursively instantiated from 'const size_t isqrt_impl<25u, 4u
, 5u>::square_root'
test.cpp:6:119: instantiated from 'const size_t isqrt_impl<25u, 1u, 3u>::squar
e_root'
test.cpp:11:69: instantiated from 'const size_t isqrt<25u>::square_root'
test.cpp:15:29: instantiated from here
test.cpp:6:119: error: incomplete type 'isqrt_impl<25u, 1048576u, 2049u>' used i
n nested name specifier
Cảm ơn tất cả,
Độ sâu đệ quy thực tế nếu bạn làm điều đó bằng cách sử dụng hàm đệ quy? – sharptooth
@sharptooth Nó xảy ra với bất kỳ giá trị nào, không phải là giá trị được sử dụng đang gây tràn. – AraK