I have a class like
template <unsigned N>
class TEST {
public:
template <unsigned P, unsigned I> struct test { static __forceinline void Run() { std::cout << 0 << std::endl; } };
template <unsigned I> struct test <N, I> { static __forceinline void Run() { std::cout << 1 << std::endl; } };
};
what I want to realize is to cout
"1" when P==N
, however I found when I run
TEST<0>::test<0, 10>::Run();
it still gives 0
.
Later I found when there is only one parameter in the template list it works:
template <unsigned N>
class TEST {
public:
template <unsigned P> struct test { static __forceinline void Run() { std::cout << 0 << std::endl; } };
template <> struct test <N> { static __forceinline void Run() { std::cout << 1 << std::endl; } };
};
though it looks simple, but what is the mechanism there, and how should I make it work when there two parameters?
EDIT
As m.s. has pointed out that, this code can do its job on a gcc compiler on Wandbox, but it just fails on my vs2013. Anyone knows why?
As Petr points out, the funny thing is that on MSVS, when P==I
the result is "1".
When I changed the code to:
template <typename N>
class TEST {
public:
template <typename P, unsigned I> struct test { static __forceinline void Run() { std::cout << 0 << std::endl; } };
template <unsigned I> struct test <N, I> { static __forceinline void Run() { std::cout << 1 << std::endl; } };
};
TEST<int>::test<int, 10>::Run();
gives "1".
As mentioned by other answers, this problem definitely looks to be a bug in VS. Before MS fix this bug, I found one solution to realize the same function:
template <unsigned N>
class TEST {
public:
template <unsigned P, unsigned I, bool Specialize = (N==P)> struct test { static void Run() { std::cout << 0 << std::endl; } };
template <unsigned P, unsigned I> struct test <P,I,true> { static void Run() { std::cout << 1 << std::endl; } };
};
which gives "1" when P==N
, otherwise "0".
The above solution has passed tests on both VS2013 and gcc5.2.0.