类非类型模板参数上的c++成员函数模板专用化
c++ member function template specialization on class non-type template parameter
从以下示例开始:
#include <cstdio>
template<int X, int Y>
struct C {
template<int Z> void bar() {printf("Generic %d/%dn",X,Y);}
void foo() {bar<Y>();}
};
int
main(int argc, char *argv[])
{
C<0,0> c0;
c0.foo();
C<0,1> c1;
c1.foo();
}
我现在想定义附加的";CCD_ 1";专门研究";Y
";。特别是类似下面插入的行(对不起,我不知道如何突出显示它们(:
#include <cstdio>
template<int X, int Y>
struct C {
template<int Z> void bar() {printf("Generic %d/%dn",X,Z);}
template<> void bar<1>() {printf("Special %d/1n",X);}
void foo() {bar<Y>();}
};
template<int X> template<> C<X,2>::bar<2>() {printf("Special %d/2n",X);}
int
main(int argc, char *argv[])
{
C<0,0> c0;
c0.foo();
C<0,1> c1;
c1.foo();
}
遗憾的是,这两种方法似乎都不是有效的/compile(gcc/9.3.0,-std=c++11(。例如:
tempspec.cpp:94:12: error: explicit specialization in non-namespace scope ‘struct C<X, Y>’
94 | template<> void bar<1>() {printf("Special %d/1n",X);}
| ^
tempspec.cpp:94:26: error: template-id ‘bar<1>’ in declaration of primary template
94 | template<> void bar<1>() {printf("Special %d/1n",X);}
| ^
tempspec.cpp:97:33: error: expected initializer before ‘<’ token
97 | template<int X> void C<X,2>::bar<2>() {printf("Special %d/2n",X);}
| ^
我知道我不能部分专门化一个函数(这是我真正想做的(,但我认为我在这里是部分专门化结构,而完全专门化函数。
所以问题是,我如何定义";CCD_ 3";作为成员功能?
(至于为什么,假设"bar()
"是模版计算,"Y
"是模版的大小。基于"Y
",我可能有针对特定大小优化的不同实现。(
至于原因,请说"条";是模版计算;Y";是模具的大小。基于";Y";我可能有针对特定大小优化的不同实现。
所以我的建议是:避免专业化,并在标记调度中使用重载。
一般情况下的一个模板bar()
特殊情况下的一些非模板bar()
#include <iostream>
template <int X, int Y>
struct C
{
template <typename T>
void bar (T const &)
{ std::cout << "Generic " << X << '/' << Y << 'n'; }
void bar (std::integral_constant<int, 1> const &)
{ std::cout << "Special " << X << '/' << 1 << 'n'; }
void bar (std::integral_constant<int, 2> const &)
{ std::cout << "Special " << X << '/' << 2 << 'n'; }
void bar (std::integral_constant<int, 4> const &)
{ std::cout << "Special " << X << '/' << 4 << 'n'; }
void foo ()
{ bar(std::integral_constant<int, Y>{}); }
};
int main ()
{
C<0,0>{}.foo();
C<0,1>{}.foo();
C<0,2>{}.foo();
C<0,3>{}.foo();
C<0,4>{}.foo();
C<0,5>{}.foo();
}
不允许直接做你想做的事。显式专门化要求为所有模板参数指定显式值。这意味着类模板参数和成员函数模板参数。例如,这将是合法的:
template<>
template<>
void C<1,1>::bar<1>() { printf("Special %d/1n",1); }
但是,如果您不使用template<>
,那么您要么是在定义以前声明的成员,要么是在部分专门化领域,但由于函数重载和部分专门化之间的冲突,部分专门化只允许用于类模板和变量模板。
请注意,显式专门化不是模板(尽管有bar()
0语法(。这就是为什么它不出现在类模板中很重要。
然而,这些类型的问题可以通过使用一个单独的类模板来解决,您可以部分专门化这个模板:
#include <cstdio>
template<int X, int Y> struct C;
template <int X, int Y, int Z>
struct CBar {
static void bar(C<X,Y> &) {
printf("Generic %d/%dn",X,Z);
}
};
template <int X, int Y>
struct CBar<X,Y,1> {
static void bar(C<X,Y> &) {
printf("Special %d/%dn",X,1);
}
};
template <int X>
struct CBar<X,2,2> {
static void bar(C<X,2> &) {
printf("Special %d/%dn",X,2);
}
};
template<int X, int Y>
struct C {
template<int Z> void bar() { CBar<X,Y,Z>::bar(*this); }
void foo() {bar<Y>();}
};
int main(int , char *[])
{
C<0,0> c0;
c0.foo();
C<0,1> c1;
c1.foo();
C<0,2> c2;
c2.foo();
}
程序标准输出
Generic 0/0
Special 0/1
Special 0/2
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 助记符和指向成员语法的指针
- 用于访问容器<T>数据成员的正确 API
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 嵌套在类中时无法设置成员数据
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 将函数类成员映射到类本身内部
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 将公共但非静态的成员函数与ALGLIB集成
- 多成员Constexpr结构初始化
- 我们可以访问一个不存在的联盟的成员吗