如何检查功能模板是否专业?
如果某个功能模板是专门的,是否有办法在编译时间建立?
例如,假设以下功能模板:
template<size_t N>
void foo();
我想测试是否 foo&lt; 42&gt;
是专门的。请注意,上面的声明不包含任何默认实现。
我尝试了Sfinae,但找不到编译器无法从声明中推断出的功能的条件。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有一个功能...我不这么认为。
但是,如果创建函数,则可以添加一个静态const成员(
is_specialized
,在下面的示例中)可以为您提供此信息---编辑---编辑----
以下Quentin的建议(再次感谢!)我已经开发了另一个基于函数的解决方案,该解决方案使用某些东西,以检测函数是通用或专业的,仅在通用函数中添加。在这种情况下,类型<代码> bool 常数。
这种类型可以通过Sfinae使用,我建议基于
constexpr
isspecialized()
模板函数(带有辅助功能)的示例,这需要更多的工作,但是
可以用不同的函数(
im_not_specialized
基于类型)重复使用Isspecialized()以下是一个完整的工作示例
With a function... I don't think so.
But if you create a functor, you can add a static const member (
is_specialized
, in the following example) that can give you this information--- EDIT ---
Following the suggestion from Quentin (thanks again!) I've developed another functor-based solution that use something, to detect if the functor is generic or specialize, that is added only in the generic functor. In this case, a type instead a
bool
constant.This type can be used via SFINAE and I propose an example based on a
constexpr
isSpecialized()
template function (with an helper function)This require a little more work but
isSpecialized()
can be reused with different functors (im_not_specialized
type based)The following is a full working example
如果将基本函数标记为已删除(
= delete
),则可以检测使用Sfinae是否已专业(假设专业化本身未删除),例如
exptype(foo&lt; n&gt) ;(())
如果foo&lt; n&gt;
标记为已删除,则会导致替换失败。如果您提供了未删除的专业,则表达式不会导致错误。使用此功能您可以创建一个简单的特质类,以检查
foo
是否专门用于一组模板参数:1。基本示例
C ++ 11: godbolt
使用C ++ 20,您也可以为此使用一个概念,例如: godbolt
2。由于函数为
= delete
'd提供默认实现,因此无法具有默认实现。
如果确实需要该函数的默认实现,则可以使用2个函数:
= delete
'd(因此,Sfinae可以检测到它)C ++ 11: godbolt
或c ++ 20: godbolt
3。编译时代的恶作剧,
这当然也可以用来迭代专业化(在一定限制内) -或您在评论中要求找到该功能最近的专业化。
最近的_foo_specialized
在此示例中将迭代n
的一系列值,并检查是否存在此值的foo
的专业化。n
是我们要启动搜索的值searchrange
确定从提供的n
中检查了多少个专业(均可向上和向下)值(在此示例中,我们检查n
's +/- 10)currentDistance
保持跟踪我们已经搜索过的距离n 值,因此我们不会超过指定的
searchrange
,例如:
最近的_foo_specialized&lt; 100,100,10&gt;
将检查的专业知识foo
n = 90
和n = 110
,返回接近100的示例)C ++ 11: godbolt
If you mark the base function as deleted (
= delete
), you can detect if it has been specialized using SFINAE (assuming the specialization itself is not deleted)An expression like
decltype(foo<N>())
will result in a substitution failure iffoo<N>
is marked as deleted. If you provide a specialization that is not deleted on the other hand the expression will not result in an error.Using this you can create a simple trait class to check if
foo
has been specialized for a specific set of template parameters:1. Basic examples
C++11: godbolt
With C++20 you could also use a concept for this, e.g.: godbolt
2. Providing a default implementation
Due to the function being
= delete
'd it can't have a default implementation.If you do require a default implementation for the function, you could use 2 functions instead:
= delete
'd (so SFINAE can detect it)C++11: godbolt
Or with C++20: godbolt
3. Compile-time shenanigans
This can of course also be used to iterate the specializations (within a certain limit) - or like you asked in the comments to find the nearest specialization of the function.
nearest_foo_specialized
in this example will iterate over a range of values forN
and check if a specialization offoo
exists for this value.N
is the value where we want to start the searchSearchRange
determines how many specializations will be checked (both up and down) from the providedN
value (in this example we check forN
's +/- 10)CurrentDistance
keeps track how far we've already searched from our startingN
value, so we don't exceed the specifiedSearchRange
e.g.:
nearest_foo_specialized<100, 10>
would check for specializations offoo
betweenN = 90
andN = 110
, returning the one that is closer to 100 (prefering lowerN
values in case of a draw)Example C++11: godbolt