C++ 类模板参数推导

在 C++17 之前,你必须在初始化变量时指定所有的模板参数,因为为了实例化类模板,所有的参数都必须是已知的,例如:

1
2
3
std::pair<int, char const*> p{ 42, "demo" };
std::vector<int> v{ 1, 2 };
foo<int> f{ 42 };

当然,使用函数模板(例如 std::make_pair())可以避免显式指定模板参数的问题,这得益于函数模板参数的推导,允许我们编写如下代码:

1
auto p = std::make_pair(42, "demo");

对于下面这个 foo 类模板,我们可以编写以下 make_foo() 函数模板来达到相同的效果:

1
2
3
4
5
6
7
template <typename T>
constexpr foo<T> make_foo(T&& value)
{
return foo{ value };
}

auto f = make_foo(42);

在 C++17 中,对于前面列举的示例,我们没有必要那样做。我们可以像下面这样编写代码:

1
std::pair p{42, "demo"};

C++17 中可以跳过指定模板参数,编译器在以下情况下可以推导出它们:

  1. 当声明变量或变量模板并初始化它时:
1
2
3
std::pair p{ 42, "demo" };  // deduces std::pair<int, char const*>
std::vector v{ 1, 2 }; // deduces std::vector<int>
std::less<> l; // deduces std::less<void>
  1. 当使用 new 表达式创建对象时:
1
2
3
4
5
6
7
8
9
template <class T>
struct foo
{
foo(T v) :data(v) {}
private:
T data;
};

auto f = new foo(42);
  1. 当执行类似函数的强制转换表达式时:
1
2
3
4
5
6
7
std::mutex mx; 

// deduces std::lock_guard<std::mutex>
auto lock = std::lock_guard(mx);std::vector<int> v;

// deduces std::back_insert_iterator<std::vector<int>>
std::fill_n(std::back_inserter(v), 5, 42);

C++ 类模板参数推导
http://example.com/2026/05/28/C++-类模板参数推导/
作者
Yu xin
发布于
2026年5月28日
许可协议