C++17: 类模板参数推导
·
1. 介绍及例子
简称叫CTAD: class template argument dedution,类模板参数推导。
就是在使用模板类的时候,你可以不用显式的指定参数的类型了。
而是由编译器自动进行推导。
比如说:
#include <utility>
#include <iostream>
#include <vector>
int main()
{
std::vector arr = { 1,2,3 };
for (auto &v: arr) {
std::cout << v << " ";
}
std::cout << "\n";
std::pair p = {1.1f,-2.0f};
std::cout << p.first << " " << p.second << std::endl;
return 0;
}
2. 类模板推断指引
但是C++坑就坑在它永远有填不完的坑,C++17的类模板参数
推导它不支持聚合类。
比如下面代码:
p2就无法推导出来!!!
#include <iostream>
template<typename T, typename U>
struct Pair {
T t{};
U u{};
};
int main()
{
Pair<int,int> p1{10,10};
Pair p2{20,20};
return 0;
}
编译器会提示没有匹配的类型。
ctad_agg_guide.cc: In function ‘int main()’:
ctad_agg_guide.cc:19:18: error: class template argument deduction failed:
19 | Pair p2{20,20};
| ^
ctad_agg_guide.cc:19:18: error: no matching function for call to ‘Pair(int, int)’
这时我们需要手动给这个模样写推导的指引:
template <typename T, typename U>
Pair(T, U) -> Pair< T, U >;
加上之后就可以推导了。
不过这个坑在C++20好像就填了。
顺带一提这个类型模板是可以带默认的参数的。
template<typename T = int, typename U = int>
struct Pair {
T t{};
U u{};
};
int main() {
Pair p; // default Pair<int, int>
return 0;
}
3. 非静态成员初始化
对于类里面的非静态成员初始化,是无法使用类模板推导的。
需要手动指定参数的类型!!!
#include <utility> // for std::pair
struct Foo
{
std::pair<int, int> p1{ 1, 2 }; // ok, template arguments explicitly specified
std::pair p2{ 1, 2 }; // compile error, CTAD can't be used in this context
};
int main()
{
std::pair p3{ 1, 2 }; // ok, CTAD can be used here
return 0;
}
这里p2会报错
ctad_nonstatic_init.cc:6:5: error: invalid use of template-name ‘std::pair’ without an argument list
6 | std::pair p2{2,3};
4. 参考
更多推荐


所有评论(0)