In the previous article, we used Enum to simulate the number of compile times, but the constants in C ++ compilation are also of the type (C only has int and double. What? You do not know sizeof ('1') = sizeof (1)?) in C )?). Therefore, it is normal for many compilers to spit out a large number of warnings. But who should be compatible with vc6? Alas, I have prepared several macros for you to choose compilation, and also adjusted the code layout. If you want to compile on some non-standard compilers, you must be prepared to receive warnings. If you are a serious boost syndrome patient, do you think the following dishes suit your appetite?
(Select macro static_const: Select Enum or static const as the method for defining constants during compilation. In essence, the former only supports int, and Intel compiler often fails when converting negative numbers. When used as bool, the compiler will warn that the warning formats are different, but almost all compilers support it, no error is reported, and the compatibility is the best. The latter is very accurate, but vc6 does not support .....)
Serving dishes.
<Br/> # include <iostream> <br/> using namespace STD; <br/> // # define static_const (type, name, value) static const type name = type (value) // try the one below if your compiler doesn't support static Const. <br/> # define static_const (type, name, value) Enum {name = type (value)} // some compiler will crash so be careful! Warning comes if size_t is not used! <Br/> static_const (size_t, stop_tag,-1); <br/>/* binary search between [M1, M2] */<br/> template <size_t N, size_t M1, size_t m2> // assert M1 <= m2 <= n <br/> struct sqrt_check <br/> {<br/> protected: <br/> static_const (size_t, middle, (M1 + m2)/2); <br/> static_const (bool, end, (m1 * m1 = n | m2 * M2 = n | M1 = Middle | middle * middle = n); <br/> static_const (bool, selector, middle * middle> N); </P> <p> Public: <br/> static_const (size_t, result, (<br/> N = m1 * m1? <Br/> m1: N = m2 * m2? <Br/> M2: M1 = middle? // | M1-M2 | = 1, which means m1 * m1 <= n <= m2 * M2 <br/> m1: N = middle * middle? // Bsearch begin! <Br/> middle: Selector? <Br/> sqrt_check <End? Stop_tag: N, end? Stop_tag: M1, end? Stop_tag: middle >:: result <br/>: sqrt_check <End? Stop_tag: N, end? Stop_tag: middle, end? Stop_tag: M2 >:: result) <br/>); <br/>}; <br/> template <> <br/> struct sqrt_check <stop_tag, stop_tag, stop_tag> <br/>{< br/> static_const (size_t, result, stop_tag); // stop here! <Br/>}; <br/> template <size_t N, size_t M1, size_t m2> <br/> struct sqrt_check_newton <br/>{< br/> protected: <br/> static_const (size_t, next, (M1 + N/M1)/2); // Newton iterator method <br/> static_const (bool, end, (next = m1 | next = m2 | next * Next = n); <br/> Public: <br/> static_const (size_t, result, (<br/> (n = next * Next | M1 = NEXT )? // Fixed point <br/> next: m2 = next? // | M1-M2 | = 1, which means m1 * m1 <= n <= m2 * M2 swing back and forth <br/> (M2 + M1)/2: sqrt_check_newton <(end? Stop_tag: N), (end? Stop_tag: Next), (end? Stop_tag: M1) >:: result) <br/>); <br/>}; <br/> template <> <br/> struct sqrt_check_newton <stop_tag, stop_tag, stop_tag> <br/>{< br/> static_const (size_t, result, stop_tag); // stop here! <Br/> }; <br/>/* Get the SQRT result of N */<br/> template <size_t n> <br/> struct sqrt_nature <br/> {<br/> // static_const (size_t, result, (sqrt_check <n, 1, n/2 + 1>: result); // begin searching between [1, n/2 + 1] <br/> static_const (size_t, result, (sqrt_check_newton <n, n/2, N >:: result )); <br/> static_const (bool, square, result * result = N); <br/> }; <br/> template <> <br/> struct sqrt_nature <1> <br/> {< Br/> static_const (size_t, result, 1); <br/> static_const (bool, square, true); <br/> }; <br/> template <> <br/> struct sqrt_nature <0> <br/> {<br/> static_const (size_t, result, 0 ); <br/> static_const (bool, square, true); <br/> }; <br/>/* Check if n % d = 0 */<br/> template <size_t N, size_t D> <br/> struct prime_check <br/> {<br/> protected: <br/> static_const (bool, Mod, N % d = 0 ); <br/> Public: <br/> stat Ic_const (bool, Prime, (<br/> d = 1? <Br/> true: MoD? <Br/> false: prime_check <MoD? Stop_tag: N, MoD? Stop_tag: d-1 >:: prime) <br/>); <br/>}; <br/> template <> <br/> struct prime_check <stop_tag, stop_tag> <br/>{< br/> static_const (bool, Prime, false); <br/> }; <br/>/* Check if n is a prime */<br/> template <size_t n> <br/> struct prime_nature <br/>{< br/> static_const (bool, prime, (prime_check <n, sqrt_nature <n >:: result >:: prime); <br/> static_const (bool, composite ,! Prime); <br/>}; <br/> template <> <br/> struct prime_nature <1> <br/>{< br/> static_const (bool, prime, false); <br/> static_const (bool, composite, false); <br/>}; <br/>/* Get the Count of prime smaller than N. */<br/> template <size_t n> <br/> struct prime_count_nature <br/> {<br/> static_const (size_t, prime_count, (prime_count_nature <N-1> :: prime_count + (prime_nature <n >:: Prime? 1: 0); <br/> static_const (size_t, composite_count, N-prime_count-1); <br/> }; <br/> template <> <br/> struct prime_count_nature <1> <br/> {<br/> static_const (size_t, prime_count, 0 ); <br/> static_const (size_t, composite_count, 0); <br/>}; <br/>/* the following 4 macros are used for test. you can uncomment any of 4. */<br/> # define test (X)/<br/> do {/<br/> If (bool (prime_nature <X >:: prime )) /<br/> cou T <x <Endl;/<br/>} while (false) <br/> // # define test (x) cout <prime_count_nature <x> :: prime_count <Endl <br/> // # define test (x) cout <x <''<(bool (prime_nature <x>: PRIME )? "Yes": "no") <Endl <br/> // # define test (x) cout <x <''<sqrt_nature <x> :: result <Endl <br/>/* test from 1 to n */<br/> template <size_t n> <br/> struct test_nature: public test_nature <N-1> <br/>{< br/> test_nature (): test_nature <N-1> () {test (n) ;}< br/> }; <br/> template <> <br/> struct test_nature <1> <br/>{< br/> test_nature () {test (1 );} <br/>}; <br/> int main () <br/>{< br/> test_nature <200> X; // vc6.0 will crash for nesting template over 225 <br/> // test (8); <br/> return 0; <br/>}< br/>
In fact, it is not impossible to filter out the warnings when using Enum, as long as you are willing to accept the 10 times that make the code hard to understand, and it is full of inexplicable forced conversions everywhere.
Secretly tell you a little secret: Brother's vc6 Standard Edition compiler threw 412 warnings, the redirected file is up to 1 m.
(The end of the entire drama .)
Note: My brother has been resting for a long time and may be busy again recently. This blog may not be updated for a long time. If you have any questions, please leave a message.