Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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,我试图使用STL列表作为函数的模板参数。该函数应该用于各种数据类型,因此我在其原始声明中将该函数定义为template,而不是template。我现在想专门研究它,以支持模板类 template<class T> void function(T param) { // do something with T } template<template <class T, class Allocator> class listPlaceholder> vo

我试图使用STL列表作为函数的模板参数。该函数应该用于各种数据类型,因此我在其原始声明中将该函数定义为
template
,而不是
template
。我现在想专门研究它,以支持模板类

template<class T> 
void function(T param)
{
  // do something with T
}

template<template <class T, class Allocator> class listPlaceholder> 
void function(std::list<T, Allocator> param)
{
  // do something with every element in param (I actually need to know it's a list)
  std::list<T, Allocator>::iterator current = param.begin();
  std::list<T, Allocator>::iterator end = param.end();

  do {
    function<T>(*current);
  } while (++current != end);
}
模板
空洞函数(T参数)
{
//用T做点什么
}
样板
无效函数(标准::列表参数)
{
//对param中的每个元素都做些什么(我实际上需要知道它是一个列表)
std::list::iterator current=param.begin();
std::list::iterator end=param.end();
做{
功能(*电流);
}而(++电流!=结束);
}
问题是,当我试图编译这段代码(在GCC下)时,它说
T
Allocator
没有在范围中定义。我的主要问题是“我如何专门研究模板类?”第二,如果可能的话,“我如何提取模板参数?”


如前所述,我正在学习模板编程,因此欢迎使用明显的解决方案。

使用
typename
作为:

typename std::list<T, Allocator>::iterator current = param.begin();
typename std::list<T, Allocator>::iterator end = param.end();

使用
typename
作为:

typename std::list<T, Allocator>::iterator current = param.begin();
typename std::list<T, Allocator>::iterator end = param.end();

您想声明这些参数吗

template<template <class T, class Allocator> class listPlaceholder, 
         class T, class Allocator> 
void function(listPlaceholder<T, Allocator> param)
{
  // do something with every element in param (I actually need to know it's a list)
  typename listPlaceholder<T, Allocator>::iterator current = param.begin();
  typename listPlaceholder<T, Allocator>::iterator end = param.end();

  do {
    function<T>(*current);
  } while (++current != end);
}
重要的是参数的类型,我也可以编写
void(*p)(int,int)
。在您的情况下,重要的是两个参数都是类型参数。因此,您也可以将模板参数编写为
模板类listPlaceholder
,完全等效


最后但并非最不重要的一点是,我想强调的是,您没有专门化
函数
,但您已经用另一个模板重载了它。因此,两个
function
s是两个完全不同的函数模板

要声明这些参数吗

template<template <class T, class Allocator> class listPlaceholder, 
         class T, class Allocator> 
void function(listPlaceholder<T, Allocator> param)
{
  // do something with every element in param (I actually need to know it's a list)
  typename listPlaceholder<T, Allocator>::iterator current = param.begin();
  typename listPlaceholder<T, Allocator>::iterator end = param.end();

  do {
    function<T>(*current);
  } while (++current != end);
}
重要的是参数的类型,我也可以编写
void(*p)(int,int)
。在您的情况下,重要的是两个参数都是类型参数。因此,您也可以将模板参数编写为
模板类listPlaceholder
,完全等效


最后但并非最不重要的一点是,我想强调的是,您没有专门化
函数
,但您已经用另一个模板重载了它。因此,两个
function
s是两个完全不同的函数模板

g++
在这里实际上是正确的;您尚未在此范围内声明
t
Allocator
。您拥有的模板声明

template<template <class T, class Allocator> class listPlaceholder> 
    void function(std::list<T, Allocator> param)
因为它相当于

template<template <class, class> class listPlaceholder> 
    void function(std::list<T, Allocator> param)
void DoSomething(void function(int, int)) {
    x = 5; // Error!
}
我相信您要做的是将模板函数签名更改为如下所示:

template<class T, class Allocator> 
    void function(std::list<T, Allocator> param)
模板
无效函数(标准::列表参数)

这表示“此函数在两种类型上参数化。当作为参数提供在类型和分配器上参数化的
std::list
时,此函数的主体可以将这些类型称为
T
allocator

g++
在这里实际上是正确的;您尚未在此范围内声明
t
Allocator
。您拥有的模板声明

template<template <class T, class Allocator> class listPlaceholder> 
    void function(std::list<T, Allocator> param)
因为它相当于

template<template <class, class> class listPlaceholder> 
    void function(std::list<T, Allocator> param)
void DoSomething(void function(int, int)) {
    x = 5; // Error!
}
我相信您要做的是将模板函数签名更改为如下所示:

template<class T, class Allocator> 
    void function(std::list<T, Allocator> param)
模板
无效函数(标准::列表参数)

这表示“此函数在两种类型上参数化。当作为参数提供时,
std::list
在类型和分配器上参数化,此函数体可以将这些类型称为
T
allocator

这是正确的,但这不是导致OP问题中报告的错误的原因。这是事实,但这不是导致OP问题中报告的错误的原因。谢谢,这很好地解释了问题。这是否意味着我将不得不重新声明原始函数,不进行专门化,但使用这些额外的模板参数,然后将2模板函数专门化到列表中?您如何使用1模板类实现相同的结果,而不将其与原始函数混淆?如果您希望有一个通用的“除列表外的其他内容”函数和一个更专门的“仅用于列表”函数,然后,您可以将第一个版本作为模板函数编写,该模板函数接受某种类型的
T
,第二个函数如上所述。在过载解决过程中,C++总是会选择更专业的功能。谢谢你的帮助,它非常有用:谢谢,这就很好地解释了这个问题。这是否意味着我将不得不重新声明原始函数,不进行专门化,但使用这些额外的模板参数,然后将2模板函数专门化到列表中?您如何使用1模板类实现相同的结果,而不将其与原始函数混淆?如果您希望有一个通用的“除列表外的其他内容”函数和一个更专门的“仅用于列表”函数,然后,您可以将第一个版本作为模板函数编写,该模板函数接受某种类型的
T
,第二个函数如上所述。在过载解决过程中C++将始终选择更专业的功能。谢谢您的帮助,它非常有用:“我使用<代码> ListPoxHyth和 STD::列表< /Cord>,专门针对<代码> STD::列表< /Cult> s,同时保持其他两个参数模板类的任何特殊性。(例如,我也在使用
std::pair
)。正如我对其他评论员提到的,附加的模板参数是否意味着您不能将此修改后的函数与原始函数一起使用。@fuseinabowl,啊,我明白了。好吧,由于您没有专门化,您不需要为任何其他专门化“保持打开”它