C++17中模板参数auto的优点
Advantages of auto in template parameters in C++17
auto
在将(可能)随 C++17 引入的模板参数中的优点是什么?
当我要实例化模板代码时,它只是auto
的自然扩展吗?
auto v1 = constant<5>; // v1 == 5, decltype(v1) is int
auto v2 = constant<true>; // v2 == true, decltype(v2) is bool
auto v3 = constant<'a'>; // v3 == 'a', decltype(v3) is char
我还能从该语言功能中获得什么?
在芬兰奥卢举行的 ISO C++ 2016 会议上,template <auto>
功能 (P0127R1) 被接受到 C++ 中。
模板参数中的 auto
关键字可用于指示 non-type 参数,其类型在实例化时推导。将此视为更方便的写作方式会有所帮助:
template <typename Type, Type value>
例如,
template <typename Type, Type value> constexpr Type constant = value;
constexpr auto const IntConstant42 = constant<int, 42>;
现在可以写成
template <auto value> constexpr auto constant = value;
constexpr auto const IntConstant42 = constant<42>;
您不再需要明确说明类型。 P0127R1 还包括一些简单但很好的示例,其中使用 template <auto>
和可变模板参数非常方便,例如 compile-time 的实现列出常量值:
template <auto ... vs> struct HeterogenousValueList {};
using MyList1 = HeterogenousValueList<42, 'X', 13u>;
template <auto v0, decltype(v0) ... vs> struct HomogenousValueList {};
using MyList2 = HomogenousValueList<1, 2, 3>;
在pre-C++1z中,而HomogenousValueList
可以简单写成
template <typename T, T ... vs> struct Cxx14HomogenousValueList {};
using MyList3 = Cxx14HomogenousValueList<int, 1, 2, 3>;
如果不将值包装在其他一些模板中,则无法编写 HeterogenousValueList
的等价物,例如:
template <typename ... ValueTypes> struct Cxx14HeterogenousValueList {};
using MyList4 = Cxx14HeterogenousValueList<constant<int, 42>,
constant<char, 'X'> >;
实际上,mceo(原始)答案中的实际值的情况未明确涵盖为非类型模板参数。
template <auto ... vs> struct HeterogenousValueList {};
using MyList1 = HeterogenousValueList<42, 'X', 1.3f>;
参见上述提案中给出的示例:
修改§14.3.2第2段:
template<auto n> struct B { /* ... */ };
B<5> b1; // OK: template parameter type is int
B<'a'> b2; // OK: template parameter type is char
B<2.5> b3; // error: template parameter type cannot be double
几天前我自己也被同样的误解绊倒了。
这是另一个示例(最初由 as an answer for 提供):
在不知道其类型的情况下提取 SIZE 的值:
template<std::size_t SIZE>
class Foo {};
template <template<auto> class T, auto K>
auto extractSize(const T<K>&) {
return K;
}
int main() {
Foo<6> f1;
Foo<13> f2;
std::cout << extractSize(f1) << std::endl;
std::cout << extractSize(f2) << std::endl;
}
C++20 似乎增加了另一种用法
...但它没有:-(
concepts 技术规范允许函数参数带有 auto
模板参数占位符,例如:
void printPair(const std::pair<auto, auto>& p) {
std::cout << p.first << ", " << p.second << std::endl;
}
但后来在 C++20 规范中被删除了。
这是一个很好的用法...
我希望它能在 C++23 中再次出现!
参见:
auto
在将(可能)随 C++17 引入的模板参数中的优点是什么?
当我要实例化模板代码时,它只是auto
的自然扩展吗?
auto v1 = constant<5>; // v1 == 5, decltype(v1) is int
auto v2 = constant<true>; // v2 == true, decltype(v2) is bool
auto v3 = constant<'a'>; // v3 == 'a', decltype(v3) is char
我还能从该语言功能中获得什么?
在芬兰奥卢举行的 ISO C++ 2016 会议上,template <auto>
功能 (P0127R1) 被接受到 C++ 中。
模板参数中的 auto
关键字可用于指示 non-type 参数,其类型在实例化时推导。将此视为更方便的写作方式会有所帮助:
template <typename Type, Type value>
例如,
template <typename Type, Type value> constexpr Type constant = value;
constexpr auto const IntConstant42 = constant<int, 42>;
现在可以写成
template <auto value> constexpr auto constant = value;
constexpr auto const IntConstant42 = constant<42>;
您不再需要明确说明类型。 P0127R1 还包括一些简单但很好的示例,其中使用 template <auto>
和可变模板参数非常方便,例如 compile-time 的实现列出常量值:
template <auto ... vs> struct HeterogenousValueList {};
using MyList1 = HeterogenousValueList<42, 'X', 13u>;
template <auto v0, decltype(v0) ... vs> struct HomogenousValueList {};
using MyList2 = HomogenousValueList<1, 2, 3>;
在pre-C++1z中,而HomogenousValueList
可以简单写成
template <typename T, T ... vs> struct Cxx14HomogenousValueList {};
using MyList3 = Cxx14HomogenousValueList<int, 1, 2, 3>;
如果不将值包装在其他一些模板中,则无法编写 HeterogenousValueList
的等价物,例如:
template <typename ... ValueTypes> struct Cxx14HeterogenousValueList {};
using MyList4 = Cxx14HeterogenousValueList<constant<int, 42>,
constant<char, 'X'> >;
实际上,mceo(原始)答案中的实际值的情况未明确涵盖为非类型模板参数。
template <auto ... vs> struct HeterogenousValueList {};
using MyList1 = HeterogenousValueList<42, 'X', 1.3f>;
参见上述提案中给出的示例: 修改§14.3.2第2段:
template<auto n> struct B { /* ... */ };
B<5> b1; // OK: template parameter type is int
B<'a'> b2; // OK: template parameter type is char
B<2.5> b3; // error: template parameter type cannot be double
几天前我自己也被同样的误解绊倒了。
这是另一个示例(最初由
在不知道其类型的情况下提取 SIZE 的值:
template<std::size_t SIZE>
class Foo {};
template <template<auto> class T, auto K>
auto extractSize(const T<K>&) {
return K;
}
int main() {
Foo<6> f1;
Foo<13> f2;
std::cout << extractSize(f1) << std::endl;
std::cout << extractSize(f2) << std::endl;
}
C++20 似乎增加了另一种用法
...但它没有:-(
concepts 技术规范允许函数参数带有 auto
模板参数占位符,例如:
void printPair(const std::pair<auto, auto>& p) {
std::cout << p.first << ", " << p.second << std::endl;
}
但后来在 C++20 规范中被删除了。
这是一个很好的用法... 我希望它能在 C++23 中再次出现!
参见: