Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板演绎句法差异_C++_Templates - Fatal编程技术网

C++ 模板演绎句法差异

C++ 模板演绎句法差异,c++,templates,C++,Templates,我为二叉树编写了一个基本程序,如下所示 #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

我为二叉树编写了一个基本程序,如下所示

#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);
}
#包括
#包括
模板
使用sp=std::unique\u ptr;
模板
结构节点{
节点(T值):
x(val){
}
施工进度计划和地址(T val){
左=标准::使_唯一(val);
左转;
}
常数sp和地址(T val){
右=标准::使_唯一(val);
返还权;
}
私人:
tx;
sp左;
sp权利;
};
int main(){
自动根=标准::使_唯一(5);
root->addL(10)->addR(4)->addL(12);
根->地址(14)->地址(3)->地址(15);
}
我的问题是关于这条线的

auto root = std::make_unique<Node<int>>(5);
autoroot=std::使_唯一(5);
如果我删除
模板参数,那么编译器会抱怨模板推导失败

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:
tree.cpp:44:41:错误:调用“make_unique(int)”时没有匹配函数
44 | auto root=std::make_unique(5);
|                                         ^
在/usr/include/c++/9/memory:80中包含的文件中,
来自树。cpp:2:
/usr/include/c++/9/bits/unique\u ptr.h:848:5:note:candidate:'template typename std:'u MakeUniq::'uuu single\u object std::make\u unique('u Args&&…)
848 |使|唯一(|参数&&…|参数)
|     ^~~~~~~~~~~
/usr/include/c++/9/bits/unique_ptr.h:848:5:注意:模板参数推导/替换失败:
而类似的扣减也适用于该行

left = std::make_unique<Node>(val);
left=std::使_唯一(val);
这是因为编译时结构中的代码已经推导了模板,因此不需要明确的
规范吗?这也解释了为什么类函数的签名中不需要
sp
,并且
sp
足以让编译器推断实际类型

p.S.
g++(Ubuntu9.2.1-17ubuntu1~16.04)9.2.1 20191102,
在类
节点
的范围内,
节点
也指
节点

那么在

left = std::make_unique<Node>(val); // Inside class scope
因为
make_unique
的模板参数是类型,而不是模板参数

所以你必须写:

auto root = std::make_unique<Node<int>>(5);
autoroot=std::使_唯一(5);

它被称为注入类模板名称。类模板的
节点
内部方法中出现的每一个节点都会转换为
节点
。所以你不必显式地输入t。
auto root = std::make_unique<Node>(5); // Invalid
auto root = std::make_unique<Node<int>>(5);