【发布时间】:2020-11-12 15:19:40
【问题描述】:
从下面的例子开始:
#include <cstdio>
template<int X, int Y>
struct C {
template<int Z> void bar() {printf("Generic %d/%d\n",X,Y);}
void foo() {bar<Y>();}
};
int
main(int argc, char *argv[])
{
C<0,0> c0;
c0.foo();
C<0,1> c1;
c1.foo();
}
我现在想定义额外的“bar()”函数,专门针对“Y”的值。具体类似于下面插入的行(对不起,我不知道如何突出显示它们):
#include <cstdio>
template<int X, int Y>
struct C {
template<int Z> void bar() {printf("Generic %d/%d\n",X,Z);}
template<> void bar<1>() {printf("Special %d/1\n",X);}
void foo() {bar<Y>();}
};
template<int X> template<> C<X,2>::bar<2>() {printf("Special %d/2\n",X);}
int
main(int argc, char *argv[])
{
C<0,0> c0;
c0.foo();
C<0,1> c1;
c1.foo();
}
遗憾的是,这些方法似乎都无效/编译(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/1\n",X);}
| ^
tempspec.cpp:94:26: error: template-id ‘bar<1>’ in declaration of primary template
94 | template<> void bar<1>() {printf("Special %d/1\n",X);}
| ^
tempspec.cpp:97:33: error: expected initializer before ‘<’ token
97 | template<int X> void C<X,2>::bar<2>() {printf("Special %d/2\n",X);}
| ^
我知道我不能部分特化一个函数(这是我真正想做的),但我认为我在这里部分特化了结构,并完全特化了函数。
那么问题来了,如何将“bar()”的附加规范定义为成员函数?
(至于为什么,说“bar()”是模板计算,“Y”是模板的大小。基于“Y”,我可能针对某些大小优化了不同的实现。)
【问题讨论】:
-
我认为您对模板有误解。模板参数的特化并不意味着使用一个值,而是一个类型。模板允许您为不同类型定义函数/类。它们更有可能是构建用户定义类型或函数的秘诀。 cplusplus.com/doc/oldtutorial/templates
-
@LucaJungla 可以提供值作为模板参数。它仅限于特定的简单类型。 en.cppreference.com/w/cpp/language/template_parameters
-
@justapony 您能否提供更多详细信息(更多要求)。你想达到什么目的?也许有更好的解决方案来解决您的问题。
-
没有太多额外的细节。我的“模板”示例一般说明了用例:成员函数的专用/优化版本。这似乎是模板的自然使用,我想了解我在语法上做错了什么和/或了解为什么从 C++ 语言的角度来看,以这种方式使用模板是不合理的。我对让它工作的黑客不太感兴趣(毕竟我可以把“bar”写成一个大的case语句,#ifdef,编译时间if,等等......;^));更有兴趣了解为什么这不是“正确”的方法。
-
@justapony:我已经扩展了我的答案,试图进一步了解“为什么”。让我知道更多细节是否会有所帮助。
标签: c++ templates template-specialization function-templates