【发布时间】:2020-02-13 05:42:02
【问题描述】:
我写了一个二叉树的基本程序如下
#include <iostream>
#include <memory>
template<typename T>
using sp = std::unique_ptr<T>;
template<typename T>
struct Node{
Node(T val):
x(val){
}
const sp<Node>& addL(T val){
left = std::make_unique<Node>(val);
return left;
}
const sp<Node>& addR(T val){
right = std::make_unique<Node>(val);
return right;
}
private:
T x;
sp<Node> left;
sp<Node> right;
};
int main(){
auto root = std::make_unique<Node<int>>(5);
root->addL(10)->addR(4)->addL(12);
root->addR(14)->addL(3)->addR(15);
}
我的问题是关于这条线
auto root = std::make_unique<Node<int>>(5);
如果我删除了<int> 模板参数,那么编译器会抱怨模板推导失败
tree.cpp:44:41: error: no matching function for call to ‘make_unique<template<class T> struct Node>(int)’
44 | auto root = std::make_unique<Node>(5);
| ^
In file included from /usr/include/c++/9/memory:80,
from tree.cpp:2:
/usr/include/c++/9/bits/unique_ptr.h:848:5: note: candidate: ‘template<class _Tp, class ... _Args> typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...)’
848 | make_unique(_Args&&... __args)
| ^~~~~~~~~~~
/usr/include/c++/9/bits/unique_ptr.h:848:5: note: template argument deduction/substitution failed:
而类似的推论适用于该行
left = std::make_unique<Node>(val);
这是因为结构中的代码在编译时已经推导出了模板,因此不需要明确指定<int>?这是否也解释了为什么在类函数的签名中不需要sp<Node<T>> 而sp<Node> 足以让编译器推断实际类型。
附: g++ (Ubuntu 9.2.1-17ubuntu1~16.04) 9.2.1 20191102
【问题讨论】:
-
称为注入类模板名。在您的类模板的方法内部每次出现
Node都会转换为Node<T>。所以你不必明确地放 T。