在模板参数中使用 auto:一些用法示例以及...如何使其与常量大小的 C 数组一起使用?
Use of auto in template parameters: Some usage examples and... how to make it work with constant size C arrays?
我在模板参数中使用了以下示例性的 auto(我喜欢独立于它们的理智或存在更好的替代方案,我只是试图内化 'auto in template params' 功能):
//1-Check if input is within open interval (l, h) where l & h are function parameters
//Example: int x = 5, y = fnc_y(), z = fnc_z(); auto fOk = gt_lt(z, x, y);
template<typename L, typename H, typename V> inline bool
gt_lt(const V &v, const L& l, const H& h) { return (v > l) && (v < h); }
//2-Check if input is within open interval (l, h) where l & h are auto template parameters
//Example: int z = fnc_z(); auto fOk = gt_lt<5, 45>(z);
template<auto l, auto h, typename V>
inline bool gt_lt(const V &v) { return (v > l) && (v < h); }
//3-Fill a C array (a) of known size with a value where a is a function parameter:
// char a[4]; fill_all(a, 'a');
template<typename TArrayValType, size_t N, typename TVal>
inline void fill_all(TArrayValType(&a)[N], const TVal &v) { std::fill(a, a + N, v); }
//4-Fill a C array (a) of known size with a value where a is an auto template parameter
//Can't figure out it!!! Goal: char a[4]; fill_all<a>('a');
template<auto a, **....what else to put it here?**, typename TVal>
inline void fill_all(const TVal &v) { std::fill(a, a + N, v); }
用法 4 不起作用。如何让它发挥作用?
我怀疑 中的东西会起作用,但仍然无法使其起作用...
上述用途的一个动机是避免将某些值(当它们在编译时已知时)作为函数参数传递,即使在调试模式下也是如此,以获得更好的调试性能,或者希望有时从完全优化中受益如果由于非类型参数的 auto 避免了参数传递,编译将生成更高效的代码。但是,我仍然不确定这是否有意义...
据我所知,你不能这么简单。
如你所见in this page
Array and function types may be written in a template declaration, but they are automatically replaced by pointer to object and pointer to function as appropriate.
所以你可以这样写
template <auto a, typename TVal>
inline void fill_all(const TVal &v)
{ }
// ...
static int a[4] {};
fill_all<a>(2);
但 fill_all()
将 a
的类型视为 int *
,而不是 int[4]
。
因此您可以将其用作指针,但您丢失了有关维度的信息。
我能想到的最好的方法是调用一个 constexpr
函数 return 数组的大小并将这个值作为模板参数(或函数参数)
template <typename T, std::size_t N>
constexpr std::size_t getDim (T const (&)[N])
{ return N; }
template <auto a, std::size_t N, typename TVal>
inline void fill_all (TVal const & v)
{ std::fill(a, a + N, v); }
// ...
static int a[4] {};
fill_all<a, getDim(a)>(2);
但是,不幸的是,我没有看到在显式模板参数列表中避免显式调用 getDim()
的方法。
我在模板参数中使用了以下示例性的 auto(我喜欢独立于它们的理智或存在更好的替代方案,我只是试图内化 'auto in template params' 功能):
//1-Check if input is within open interval (l, h) where l & h are function parameters
//Example: int x = 5, y = fnc_y(), z = fnc_z(); auto fOk = gt_lt(z, x, y);
template<typename L, typename H, typename V> inline bool
gt_lt(const V &v, const L& l, const H& h) { return (v > l) && (v < h); }
//2-Check if input is within open interval (l, h) where l & h are auto template parameters
//Example: int z = fnc_z(); auto fOk = gt_lt<5, 45>(z);
template<auto l, auto h, typename V>
inline bool gt_lt(const V &v) { return (v > l) && (v < h); }
//3-Fill a C array (a) of known size with a value where a is a function parameter:
// char a[4]; fill_all(a, 'a');
template<typename TArrayValType, size_t N, typename TVal>
inline void fill_all(TArrayValType(&a)[N], const TVal &v) { std::fill(a, a + N, v); }
//4-Fill a C array (a) of known size with a value where a is an auto template parameter
//Can't figure out it!!! Goal: char a[4]; fill_all<a>('a');
template<auto a, **....what else to put it here?**, typename TVal>
inline void fill_all(const TVal &v) { std::fill(a, a + N, v); }
用法 4 不起作用。如何让它发挥作用?
我怀疑
上述用途的一个动机是避免将某些值(当它们在编译时已知时)作为函数参数传递,即使在调试模式下也是如此,以获得更好的调试性能,或者希望有时从完全优化中受益如果由于非类型参数的 auto 避免了参数传递,编译将生成更高效的代码。但是,我仍然不确定这是否有意义...
据我所知,你不能这么简单。
如你所见in this page
Array and function types may be written in a template declaration, but they are automatically replaced by pointer to object and pointer to function as appropriate.
所以你可以这样写
template <auto a, typename TVal>
inline void fill_all(const TVal &v)
{ }
// ...
static int a[4] {};
fill_all<a>(2);
但 fill_all()
将 a
的类型视为 int *
,而不是 int[4]
。
因此您可以将其用作指针,但您丢失了有关维度的信息。
我能想到的最好的方法是调用一个 constexpr
函数 return 数组的大小并将这个值作为模板参数(或函数参数)
template <typename T, std::size_t N>
constexpr std::size_t getDim (T const (&)[N])
{ return N; }
template <auto a, std::size_t N, typename TVal>
inline void fill_all (TVal const & v)
{ std::fill(a, a + N, v); }
// ...
static int a[4] {};
fill_all<a, getDim(a)>(2);
但是,不幸的是,我没有看到在显式模板参数列表中避免显式调用 getDim()
的方法。