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++;接受每个类和类模板的模板?_C++_Templates_Overloading - Fatal编程技术网

C++ 如何编写C++;接受每个类和类模板的模板?

C++ 如何编写C++;接受每个类和类模板的模板?,c++,templates,overloading,C++,Templates,Overloading,预先警告:这个问题似乎比实际情况更加明显 我想写一个可以接受任何具体类或模板类作为模板参数的模板。这可能看起来没用,因为如果不知道传入的T是否是模板化的,您将不知道如何使用它。我之所以要这样做,是因为我可以声明一个没有定义的通用模板,然后用户进行专门化。因为用户对它进行了专门化,所以他们总是知道他们要处理的类型。但是,如果不首先声明模板,用户就不能专门化模板 您可以这样做: template<class T> class myclass; 模板 类myclass; 但是,如果您传

预先警告:这个问题似乎比实际情况更加明显

我想写一个可以接受任何具体类或模板类作为模板参数的模板。这可能看起来没用,因为如果不知道传入的T是否是模板化的,您将不知道如何使用它。我之所以要这样做,是因为我可以声明一个没有定义的通用模板,然后用户进行专门化。因为用户对它进行了专门化,所以他们总是知道他们要处理的类型。但是,如果不首先声明模板,用户就不能专门化模板

您可以这样做:

template<class T>
class myclass;
模板
类myclass;
但是,如果您传入一个模板化的t,那么这将不起作用,例如
myclass
将不起作用。那么我们试试这个:

template<class T>
class myclass;

template<template<class> T>
class myclass;
模板
类myclass;
模板
类myclass;
这可能是正确的方法,但它不会按原样工作,因为类模板不能重载。那么让我们切换到函数模板,它可以是:

template<class T>
void myfunc();

template<template<class> T>
void myfunc();
模板
void myfunc();
模板
void myfunc();
亲爱的,那么我们做对了?嗯,模板参数可能有不同数量的参数,所以我们也需要考虑到这一点

template<class T>
void myfunc();

template<template<class> T>
void myfunc();

template<template<class, class> T>
void myfunc();

template<template<class, class, class> T>
void myfunc();

// etc.
模板
void myfunc();
模板
void myfunc();
模板
void myfunc();
模板
void myfunc();
//等等。
丑陋,但是可以为我们生成这段代码(在C++0x中,将添加对可变模板的支持,因此这种丑陋只是暂时的)。但我们还是忘了一个案子!如果T的一个参数不是类,而是常量整数,该怎么办。让我们试着支持这一点:

template<class T>
void myfunc();

template<template<class> T>
void myfunc();

template<template<class, class> T>
void myfunc();

template<template<class, class, class> T>
void myfunc();

// etc.

template<template<class> T>
void myfunc();

template<template<class, int> T>
void myfunc();

template<template<int, class> T>
void myfunc();

template<template<int, class, class> T>
void myfunc();

template<template<class, int, class> T>
void myfunc();

template<template<class, class, int> T>
void myfunc();

// etc.
模板
void myfunc();
模板
void myfunc();
模板
void myfunc();
模板
void myfunc();
//等等。
模板
void myfunc();
模板
void myfunc();
模板
void myfunc();
模板
void myfunc();
模板
void myfunc();
模板
void myfunc();
//等等。

哦。假设任何常量类型都可以被传递到模板中,在任何数量下,与类参数混合,KABLOOEY组合爆炸。只是让事情变得更困难,如果T的任何参数本身就是模板呢

解决方案是:使用函数重载,而不是模板专门化!编译时间会更好,约束消失了

请记住,任何模板都被认为是在使用它们之后的最接近的全局范围内实例化的。这意味着这将起作用:

template <class T>
int f(const T& t)
{
  return g(t);
} 

int g(int a)
{
  return a+1;
}

int main()
{
   return f(5);
}
模板
内部f(常数T&T)
{
返回g(t);
} 
INTG(INTA)
{
返回a+1;
}
int main()
{
返回f(5);
}
如您所见,即使函数
g
是在
f
之后定义的,它也可以工作。这意味着你可以定义你想要使用函数的模板,只要用户在函数<强> >模板之前使用函数定义,你就可以了,C++会找到它。 还请记住,函数不存在模板专门化!如果存在许多同名函数,C++总是期望重载,而不是模板特化。
简而言之,最好的解决方案是:将函数当作存在一样使用,并期望用户在使用模板之前定义函数。

boost::mpl就是这样做的(这是他们的想法)。然而,你必须做出很多假设才能让它工作,比如使用

template <class T> foo { }; typedef foo< int_<4> > my_foo_4;
模板foo{};typedef foomy\u foo\u 4;
而不是

template <int T> foo { }; typedef foo<4> my_foo_4;
模板foo{};键入def foo my_foo_4;
不必为所有int、char、bool等组合提供重载

我想不出比boost::mpl方法更有效的方法了,一般来说,我认为任何方法都会遇到很多问题;类模板不是一个类型,并且不能以这种方式真正嵌入到类型系统中(boost::mpl将其视为创建新类型的函数;更一般地说,它用于创建“元函数”)。我甚至不确定可变模板是否会影响模板参数(尽管这是一个有趣的问题)。

模板类myclass;
模板类myclass{};
模板类myclass{};
模板类myclass{};

这就是你想要的吗?

问题已经使用了重载-答案没有解决这个问题。据我所知,他希望能够调用f(),f(),f()(!)等等。我不同意。。。他想为用户定义一个模板来专门化它。然后,OP建议预定义函数模板。但不能专门化函数模板。同样,如果OP想要定义这个函数,这就是在他的代码中使用它。否则,OP应该提供更多关于如何使用该功能的细节。我将回到绘图板,明确定义需求。你想要实现什么?混合使用模板和类是否有意义(注意std::vector是一个类,而不是模板)。你到底想解决什么?托德,他们会的。在C++1x中,您将能够执行模板结构Take;模板结构采用{};您也可以接受任何类型,并从模板结构Take{…}获取它们的参数;使用int_u是我想到的一个主意,但我害怕走那条路;)对于模板参数和插入参数,我也必须做同样的事情,这比我容易想象的要多一些。我想我只需要尝试一下,看看会发生什么。MPL允许轻松地使用lambdas:passVector作为类型,然后使用typename MPL::apply::type(T是模板参数),得到vectorNope。我希望能够专门化std::vector上的myclass,而不需要实际提供std::vector类型。为此,您需要模板参数。
template <class T> class myclass;

template <> class myclass<int>{};
template <> class myclass<std::vector<int>>{};
template <> class myclass<std::vector<std::vector<int> > >{};