我正在将一些C代码移植到C ++,并且遇到了一个具有以下签名的宏。 bound_check(v, l, h)
在实践中,l
和h
是(整数)常量,这使其适合于模板函数。然而,由于在C宽松类型安全(和宏的一般不良)v
,l
,h
往往不具有相同的类型。
我想确保h
和l
的类型相同(例如T
),并且T
至少可以在时间上转换为decltype(v)
。本来可以的template <typename T, T l, T h> void bound_check(...)
,但是需要手动编码的类型v
。我做出了一个(可能更危险的)假设,即所有可能的类型T
s都经过签名,并用于template <long long l, long long h>
避免对进行硬编码v
。
我想知道是否有一种方法可以像in中那样调用函数bound_check<l, h>(v)
,或者换句话说,是否有一些技巧可以用来template <T l, T h> bound_check(T& v)
在解析显式模板参数之前从参数推导类型,如标题所述。
我想确保h和l是相同的类型(例如T),
很简单:您可以将它们强加为相同的模板类型T
,因此,如果使用不同类型的值调用该函数,则会产生编译错误,因为存在歧义推断T
。
所以
template <typename U, typename T>
void bound_check (U v, T l, T h)
{ /* ... */ }
我想确保h和l是相同的类型(例如T),并且T至少可以在时间上转换为decltype(v)。
您可以使用进行检查static_assert()
(请参见Nikos C.答案),也可以SFINAE激活/停用该功能(例如,以C ++ 11的方式),如下所示
template <typename U, typename T>
typename std::enable_if<std::is_convertible<T, U>::value>::type bound_check (U & v, T l, T h)
{ /* do something with v, l and h */ }
我做出了一个(可能更危险的)假设,即所有可能的类型T均已签名
使用SFINAE,您可以添加相应的测试
template <typename U, typename T>
typename std::enable_if<std::is_convertible<T, U>::value
&& std::is_signed<T>::value>::type bound_check (U & v, T l, T h)
{ /* do something with v, l and h */ }
也许您还可以检查T
是否为整数类型(std::is_integral
):std::is_signed
对于浮点类型也为true。
如果有一些技巧可以做模板bound_check(T&v),其中在解析显式模板参数之前从参数推导类型,如标题所述。
不,据我所知。
无论如何,如果可能的话,您可以通过这种方式松开“我想确保h和l是相同类型”的检查。
如果想知道是否有一种方法可以像这样调用该函数
bound_check<l, h>(v)
从C ++ 17开始,您可以使用auto
非类型模板参数。
因此,在C ++ 17之前,我想答案是“否”。
从C ++ 17开始,您可以编写如下内容:
template <auto l, auto h, typename U>
std::enable_if_t<std::is_same_v<decltype(l), decltype(h)>
&& std::is_convertible_v<decltype(l), U>
&& std::is_integral_v<decltype(l)>
&& std::is_signed_v<decltype(l)>> bound_check (U & v)
{ /* do something with v, l and h */ }
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句