Reputation: 73
In the book that I found there's a code computing a square root of a given number, but the code doesn't compile. There is a lot of errors when instantiating the template. This is the code:
#include <iostream>
template
<int N, int LO=1, int HI=N> class Sqrt {
public:
enum { mid = (LO+HI+1)/2 };
enum { result = (N<mid*mid) ? Sqrt<N,LO,mid-1>::result : Sqrt<N,mid,HI>::result };
};
template<int N, int M> class Sqrt<N,M,M> {
public:
enum { result=M };
};
int main()
{
std::cout << Sqrt<5>::result << std::endl;
}
and many of the warnings are
enumeral mismatch in conditional expression 'Sqrt<5,1,1>::< anonymous enum> vs 'Sqrt<5,2,2>::< anonymous enum>' [-Wenum-compare]
as I tested later this warning is not critical, for example in the code
class a {
public:
enum {test = 0};
};
class b {
public:
enum {test = 1};
};
class c {
public:
enum {test = 2 < 3 ? a::test : b::test};
};
int main()
{
int v = c::test;
}
I get the same warning, but the code compiles. My confusion is caused because if I place the '-Wenum-compare' in compiler options, the first code compiles. What is the real problem here?
Upvotes: 0
Views: 1688
Reputation: 180500
To get rid of the warning you can cast the enums into their integer values. This means you have two integers instead of two different enumerations.
template
<int N, int LO=1, int HI=N> class Sqrt {
public:
enum { mid = (LO+HI+1)/2 };
enum { result = (N<mid*mid) ? static_cast<int>(Sqrt<N,LO,mid-1>::result) : static_cast<int>(Sqrt<N,mid,HI>::result) };
};
template<int N, int M> class Sqrt<N,M,M> {
public:
enum { result=M };
};
int main()
{
std::cout << Sqrt<5>::result << std::endl;
}
Will compile without warning. As for why you get these warnings even though it compiles see: Why do I get an error when directly comparing two enums?
Upvotes: 1
Reputation: 206577
Instead of enum
, you can use static constexpr int
.
template <int N, int LO=1, int HI=N> struct Sqrt {
static constexpr int mid = (LO+HI+1)/2;
static constexpr int result = (N<mid*mid) ? Sqrt<N,LO,mid-1>::result : Sqrt<N,mid,HI>::result;
};
template<int N, int M> struct Sqrt<N,M,M> {
static constexpr int result=M;
};
Upvotes: 1