针对特定类型的部分模板专业化,c++
使用模板的部分专业化,我想创建一个函数/方法:
A)仅处理形式参数的一种特定原始类型(int,double,float,...),而对于其他类型抛出异常
template <class T>
T min ( Point <T> p )
{
/*if (T == int) continue;
else throw exception*/
}
B)处理更多非-形式参数的原始类型(用户定义类型)以及引发异常的其他类型...
一些代码示例会很有帮助(无需 C++ boost 库)。感谢您的帮助。
Using partial specialization of templates I would like to create a function/method:
A) processing only one specific primitive type (int, double, float,...) of the formal parameter and for other types throwing exception
template <class T>
T min ( Point <T> p )
{
/*if (T == int) continue;
else throw exception*/
}
B) processing more non-primitive types (user defined types) of the formal parameter and for other types throwing exception...
Some code examples would be helpful (without c++ boost library). Thanks for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这就是您的问题的解决方案(A 部分)。
请参阅这些示例代码。
代码1
当 T 为 int 时。没有错误。请忽略
不过警告!
代码2
当 T 为双倍时。现在,查看错误
留言也。请忽略
不过警告!
同样,您可以为其他类型(双精度型、字符型等)编写模板。或者,更好的是,您可以简单地将所有这些合并到一个
struct
中,而可以在单个模板中定义许多 布尔值(针对每种类型),例如static const bool is_T_int = true;
。等等,做实验,你就会学到东西!但是,我想知道你是否希望你的函数只处理一种类型,那么为什么要定义模板呢?
对于(B)部分,您可以从上面得到这个想法。正确的?做实验!
This is the solution of your problem (part A).
See these sample code.
code1
when T is int. No error. Please ignore the
warning though!
code2
when T is double. Now, see the error
message also. Please ignore the
warning though!
Similarly, you can write templates for other types, (double, char, whatever). Or, even better, you can simply merge all those into just one
struct
, and instead can define many booleans (for each type) in a single template, likestatic const bool is_T_int = true;
. Etc. Do experiments, you'll learn!But then, I wonder if you want your function to handle just one type, then why define template to start with?
For part(B), you get the idea from the above. Right? Do experiments!
您可以在此处使用 boost::mpl 作为 B 部分,但这是使用 boost:(
编辑
并在编译时检查一切都更简单:
you can use boost::mpl here for part B but this is use boost:(
EDIT
with compile time check everything is simpler:
正如 Alexender C. 的评论中提到的,您确定编译错误不会更合适吗?
部分特化可用于允许给定模板的任何特化:
对于您希望支持的每种类型,您添加一个新的特化。
更新:发生了什么:
注意:我已经更改了原始版本的模板参数名称,以使事情更加清晰。
当编译器看到对
foo(x)
的调用时,它唯一可以正确特化的函数是foo(T)
。这是因为它无法推导出 foo(T) 的所有模板参数。foo(T)
的主体将调用转发给真正的函数:(旁白:请参阅 此处了解何时使用typename)
这会同时执行两件事。
第一个是提供调用其他函数所需的 2 个模板参数(S 和 T)。
第二种是使用
GateKeeper
的成员作为其他类型。类型GateKeeper
必须完整并具有该成员。正是这个检查使我们能够指定我们想要允许哪些类型以及不允许哪些类型:因为我们只提供了
GateKeeper
的定义,而不是GateKeeper的定义;
,对foo(0)
的调用工作正常,foo(0.0)
失败并出现编译错误。要允许 double ,我们只需要为其添加显式特化:
As mentioned in the comment by Alexender C., are you sure a compile error wouldn't be more suitable?
A partial specialization can be used to allow any specialization of a given template:
For each type that you wish to support you add a new specialization.
UPDATE: What is happening:
Note: I've changed the template parameter names from the original version to make things a bit clearer.
When the compiler sees a call to
foo(x)
the only function that it can correctly specialize isfoo<T>(T)
. This is because it cannot deduce all the template parameters forfoo<S,T>(T)
.The body of
foo<T>(T)
forwards the call to the real function:(ASIDE: see here for description of when to use typename)
This is doing 2 things at once.
The first is to provide the 2 template parameters (S and T) which are required to call the other function.
The second is to use a member of
GateKeeper<T>
as this other type. The typeGateKeeper<T>
must be complete and have that member. It is this check that allows us to specify which types we want to allow and which we don't:As we have only provided a definition for
GateKeeper<int>
and not forGateKeeper<double>
, the call tofoo(0)
works correctly, andfoo(0.0)
fails with a compile error.To allow
double
, we just need to add an explicit specialization for it: