通过类的模板形参特化成员模板结构
Specialize member template struct by template parameters of class
我有一个类,像
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上失败了。有人知道为什么吗?
正如peter指出的,有趣的是,在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"
以下完整代码(我删除了__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
如果你取消注释,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
。
正如其他答案所提到的,这个问题看起来肯定是VS中的一个bug。在MS修复这个bug之前,我找到了一个实现相同功能的解决方案:
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的测试。
相关文章:
- 如何在C++中定义静态成员结构
- 使用模板化类的成员结构
- 初始化固定的 C 数组成员结构
- 指向成员结构的指针如何工作
- 如何将此“指针从外部类传递到成员结构
- 导致IAR ARM中出现错误的成员结构位字段元素的Initializer列表初始化
- 映射文件中成员结构的地址
- Visual C++ 模板类成员结构初始化语法糖
- C :初始化成员结构的静态字段的正确方法
- 如何在C 类的初始化器列表中使用未命名结构初始化成员结构
- 从成员结构的成员函数中访问类的成员?
- 模板化类的成员函数无法返回指向成员结构的指针?
- 重载非类型模板结构的成员结构的复制赋值运算符
- 灵气属性传播问题与单成员结构.
- 将具有 int* 成员C++结构编接到 C#
- 复杂的班级成员结构
- 将向量成员(结构)传递给函数
- 成员结构的前向声明
- 重载运算符<<用于模板结构中定义的成员结构
- 返回带有模板化类的类成员结构