我有一个像
这样的课程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; } };
};
我想要实现的是cout
“1”P==N
,但是当我跑步时我发现
TEST<0>::test<0, 10>::Run();
它仍然提供0
。
后来我发现模板列表中只有一个参数可以工作:
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; } };
};
虽然它看起来很简单,但那里的机制是什么,当有两个参数时我应该如何使它工作?
修改
作为m.s.已经指出,这段代码可以在Wandbox上的gcc编译器上完成它的工作,但它在我的vs2013上失败了。谁知道为什么?
正如彼得指出的那样,有趣的是,在MSVS上,当P==I
结果为“1”时。
当我将代码更改为:
时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();
给出“1”。
答案 0 :(得分:1)
以下完整代码(我删除了__forceinline
以使其与gcc兼容):
#include <iostream>
template <unsigned N>
class TEST {
public:
template <unsigned P, unsigned I> struct test { static void Run() { std::cout << 0 << std::endl; } };
template <unsigned I> struct test <N, I> { static void Run() { std::cout << 1 << std::endl; } };
// template <unsigned I> struct test <I, I> { static void Run() { std::cout << 2 << std::endl; } };
};
int main() {
TEST<2>::test<2, 10>::Run();
TEST<2>::test<10, 10>::Run();
return 0;
}
输出
0
1
Visual Studio 2013上的和
1
0
on gcc 4.8.2。
如果取消注释注释行,gcc将给出1 2
的预期结果,而VS不会编译时出现以下错误:
1>source.cpp(12): error C2752: 'TEST<2>::test<10,10>' : more than one partial specialization matches the template argument list
1> source.cpp(7): could be 'TEST<N>::test<N,I>'
1> source.cpp(8): or 'TEST<N>::test<I,I>'
因此,MSVS似乎将(第一)专业化用于P==I
,而不是N==P
。这肯定是Visual Studio中的一个错误。
答案 1 :(得分:1)
正如其他答案所提到的,这个问题肯定是VS中的一个错误。 在MS修复此错误之前,我找到了一个实现相同功能的解决方案:
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; } };
};
在P==N
时给出“1”,否则为“0”。
上述解决方案已通过VS2013和gcc5.2.0的测试。