Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.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++ - Fatal编程技术网

C++ 模板类的部分专门化问题!

C++ 模板类的部分专门化问题!,c++,C++,下面的代码让我感到困惑 //partial specialization of vector template<class t> class vector {.... }; template<class t> //teacher said that this partial specialization will handle all type of pointers class vector<t*> ... }; //向量的部分特殊化 模板 类向量 {.

下面的代码让我感到困惑

//partial specialization of vector 
template<class t>
class vector
{....
};
template<class t>
//teacher said that this partial specialization will handle all type of pointers
class vector<t*>
...
};
//向量的部分特殊化
模板
类向量
{....
};
模板
//老师说这个部分专门化将处理所有类型的指针
类向量
...
};

这让我很困惑,假设t是char*,因为编译器会首先查找完全专门化,因为这里没有完全专门化,所以会考虑部分专门化。现在它将在部分专门化中变成char**,因为t是char*,这意味着我们没有实现我们想要的功能。请以更容易理解的方式解释。

编译器将始终查找最专业的匹配项(如果存在歧义,则将失败)

由于
char**
匹配两种模式:

char** = T*  (with T = char*)
char** = T   (with T = char**)
而前者更专业,这将被选择。(由于
char**
实际上是指向某些东西的指针,我认为“我们没有实现我们想要的功能”是错误的。)


编辑 一旦选择了专门化,所有其他候选项都将被抛出(在匹配阶段不会发生递归替换)。比如说,

template<class T> struct A {
  typedef T type;
  static const int value = 0;
};
template<class T> struct A<T*> {
  typedef T type;
  static const int value = 12;
};
template<class T> struct A<T********> {
  typedef T type;
  static const int value = 1024;
};
...
A<char**>::type x;                          // <-- Line X
std::cout << A<char**>::value << std::endl; // <-- Line Y
执行替换后,它变为

struct A<char**> {
  typedef char* type;
  static const int value = 12;
};
结构A{ typedef char*类型; 静态常数int值=12; }; X线和Y线应为

/*A<char**>::type*/ char* x;                       // <-- Line X
std::cout << /*A<char**>::value*/ 12 << std::endl; // <-- Line Y

/*A::type*/char*x;// 编译器将始终查找最专门化的匹配项(如果存在歧义,则将失败)

由于
char**
匹配两种模式:

char** = T*  (with T = char*)
char** = T   (with T = char**)
而前者更专业,这将被选择。(由于
char**
实际上是指向某些东西的指针,我认为“我们没有实现我们想要的功能”是错误的。)


编辑 一旦选择了专门化,所有其他候选项都将被抛出(在匹配阶段不会发生递归替换)。比如说,

template<class T> struct A {
  typedef T type;
  static const int value = 0;
};
template<class T> struct A<T*> {
  typedef T type;
  static const int value = 12;
};
template<class T> struct A<T********> {
  typedef T type;
  static const int value = 1024;
};
...
A<char**>::type x;                          // <-- Line X
std::cout << A<char**>::value << std::endl; // <-- Line Y
执行替换后,它变为

struct A<char**> {
  typedef char* type;
  static const int value = 12;
};
结构A{ typedef char*类型; 静态常数int值=12; };
X线和Y线应为

/*A<char**>::type*/ char* x;                       // <-- Line X
std::cout << /*A<char**>::value*/ 12 << std::endl; // <-- Line Y

/*A::type*/char*x;// 当编译器实例化向量时,它匹配以下模板:

template<class T>
class vector<T*> {
  ...
};
模板
类向量{
...
};
为了让这个模板生成一个类
vector
,它需要用
T=char
实例化,这正是编译器所做的


当编译器看到类型
vector
时,它不会使用
T=char*
来实例化模板,因为这将导致错误的类型
vector
。它将使用
T=char
,这将导致
vector
。编译器使用的模板参数将给出正确的结果类型。

当编译器实例化
向量时,它将匹配以下模板:

template<class T>
class vector<T*> {
  ...
};
template<class t>
//teacher said that this partial specialization will handle all type of pointers
class vector<t*>
{
    ...
};

vector<char*> v;
模板
类向量{
...
};
为了让这个模板生成一个类
vector
,它需要用
T=char
实例化,这正是编译器所做的

当编译器看到类型
vector
时,它不会使用
T=char*
来实例化模板,因为这将导致错误的类型
vector
。它将使用
T=char
,这将导致
vector
。编译器使用的模板参数将给出正确的结果类型

template<class t>
//teacher said that this partial specialization will handle all type of pointers
class vector<t*>
{
    ...
};

vector<char*> v;
它再次选择专门化,其中
vector
vector
T=int
匹配


它再次选择了专门化,在这里,
vector
vector
T=int

匹配,我仍然无法理解。你说char**=T*(带T=char*)char**=T(带T=char**),现在我假设T是char*,现在,如果编译器考虑部分特化,它将变成char **。如果编译器考虑以下模板类向量{…},它仍然是char *。齐亚:哪一部分让你感到困惑?我无法理解,我在上面解释了为什么我感到困惑。请试着理解我上面的评论,我仍然无法理解。你说char**=T*(带T=char*)char**=T(带T=char*)现在我假设T是char*,现在,如果编译器考虑部分特化,它将变成char **。如果编译器考虑以下模板类向量{…},它仍然是char *。齐亚:哪一部分让你困惑?我无法理解这个想法,我已经解释了为什么我会困惑,请试着理解我上面的评论。。编译器如何判断“
vector
是错误的类型”@peterchen:如果你说你想要一个
vector
(比如
vector mystorage;
),那么
vector
就错了。哦,是的!你的回答很有帮助,我明白了。大多数人没有正确阅读问题并试图回答这个问题,这对提问者来说变得非常困惑,因为你可以看到肯尼特的答案。他的答案非常复杂,学生很难理解。所以,非常感谢你。嗯。。编译器如何判断“
vector
是错误的类型”@peterchen:如果你说你想要一个
vector
(比如
vector mystorage;
),那么
vector
就错了。哦,是的!你的回答很有帮助,我明白了。大多数人没有正确阅读问题并试图回答这个问题,这对提问者来说变得非常困惑,因为你可以看到肯尼特的答案。他的答案非常复杂,学生很难理解。谢谢你,先生,你的回答非常有帮助,我理解你想表达的意思。你的答案与问题相符,非常有帮助。因此,非常感谢您。谢谢您,先生,您的回答非常有帮助,我相信