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_Variadic Templates_Template Meta Programming_Template Templates - Fatal编程技术网

C++ 嵌套模板如何在C++;?

C++ 嵌套模板如何在C++;?,c++,templates,variadic-templates,template-meta-programming,template-templates,C++,Templates,Variadic Templates,Template Meta Programming,Template Templates,我最近问了一个关于确定迭代器是否在编译时指向复杂值的问题,并得到了一个有效的答案 问题是: 解决方案是一组模板,确定一个模板是否是另一个模板的特化: template <class T, template <class...> class Template> struct is_specialization : std::false_type {}; template <template <class...> class Template, clas

我最近问了一个关于确定迭代器是否在编译时指向复杂值的问题,并得到了一个有效的答案

问题是:

解决方案是一组模板,确定一个模板是否是另一个模板的特化:

template <class T, template <class...> class Template>
struct is_specialization : std::false_type {};

template <template <class...> class Template, class... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};
模板
结构是_专门化:std::false_类型{};
模板
结构是_专门化:std::true_类型{};
这确实有效,但我真的很难理解它是如何工作的。尤其是
模板
中嵌套的
模板
让我感到困惑。我对使用可变模板还是相当陌生的,没有提供类型的可变模板似乎很奇怪,例如:
而不是像这样的


是否有人可以分解此模板并描述如何解决此问题?

您必须考虑有三种类型的模板参数:

1) 类型

2) 非类型(或值)

3) 模板

第一种类型前面有
typename
(或
class

在前面的示例中,
I
模板参数是
int
类型的值

第三类是最复杂的解释

你知道(我想)std::vector和std::vector是不同的类型,但是它们有一个共同的模板类

模板模板参数是接受
std::vector
的参数,该模板类不带参数

模板参数前面有一个
template
关键字,如下例所示

template <template <int> class C>
void baz ();
您可以将
getInt
作为模板参数传递到
baz()

当第一个模板参数(
template
)是基于第二个(
template
)的类时,将选择此专门化

例如:如果您实例化

is_specialization<std::vector<int>, std::map>

之所以选择专门化(继承自
std::true_type
),是因为
std::vector
是基于
std::vector

这是一个基于我脑海中“点击”原因的答案。说到这一点,如果你能遵循它,我相信max66答案会更有用。如果你和我一样,即使在读了这篇文章之后,你仍然在苦苦挣扎,这是我试图解释的

不要读取模板的第一行

因此:

template <class T, template <class...> class Template>
struct is_specialization : std::false_type {};

template <template <class...> class Template, class... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};
这只是意味着这是一个模板,其第二个参数是模板模板参数,这是必需的,这样您就可以将类似于
std::set
的内容作为第二个参数传递(请注意,通常这不起作用,您需要传递某种类型的
std::set

最难看的部分是第二个模板的第一行:

template <template <class...> class Template, class... Args>
模板
如果我们还记得我们在专门化代码中所做的事情,那么这里再次说明这一点。 我们有template-template-argument
template
,之所以需要
Args
,是因为我们想将template-template-argument用作普通的模板参数(作为第一个arg(
template

tl;dr

忽略模板的第一行,模式匹配


免责声明:正如我所说,这只是我向自己解释代码的方式,我知道标准的人在阅读诸如“第一行”或“模式匹配”之类的短语时会哭泣。

请每个问题回答一个问题。首先请看这里:@formerlyknownas_463035818我已经通读了那篇文章中的答案,似乎没有一个能清楚地描述它是如何工作的。他们确实展示了一些用例,但在不知道它是如何工作的情况下,没有一个用例对我来说真正有意义。我需要把它通读几遍,也许需要几天时间和几杯咖啡hahaha@tjwrona1992-是的,我想您需要了解模板参数的概念;不是很简单,我想我已经开始掌握模板参数了,但事实上,可变模板被扔进了混合中,这真的让我头疼spin@tjwrona1992也要考虑在匹配模板参数中模板模板参数和模板参数中模板参数匹配的规则是复杂的(并且考虑到我不理解我刚才写的内容)。这是否意味着有一种更干净的方法可以在C++17中编写此代码并获得相同的结果?
baz<getInt>();
template <class T, template <class...> class Template>
struct is_specialization : std::false_type {};
template <template <class...> class Template, class... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};
is_specialization<std::vector<int>, std::map>
is_specialization<std::vector<int>, std::vector>
template <class T, template <class...> class Template>
struct is_specialization : std::false_type {};

template <template <class...> class Template, class... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};
struct is_specialization : std::false_type {};

struct is_specialization<Template<Args...>, Template> : std::true_type {};
is_specialization<std::vector<double>, std::set>
template <class T, template <class...> class Template>
template <template <class...> class Template, class... Args>