简体   繁体   English

类型别名和模板模板参数推导

[英]Type aliases and template template argument deduction

Problem: 问题:

I have noticed that there is a bit of an inconsistency during template template deduction when using type aliases. 我注意到在使用类型别名时,在模板模板推导过程中存在一些不一致之处。 In particular a type alias can be used as template template argument but is not deduced as one. 特别地,类型别名可以用作模板模板参数,但不能推论为一个。

Example: 例:

We will use Matched<Type> to see if Type is an instance of a templated type. 我们将使用Matched<Type>来查看Type是否是模板类型的实例。

template <typename T>
bool Matched = false;

template <template <typename> typename F, typename T>
bool Matched<F<T>> = true;

Now define a type alias 现在定义一个类型别名

template<typename T>
using Alias = std::tuple<T,T>;

And my problem is that Matched<Alias<int>>==false . 我的问题是Matched<Alias<int>>==false However Alias can be used as a template template argument, for example: 但是, Alias可以用作模板模板参数,例如:

template<template<typename> typename F>
using ApplyInt = F<int>;

Then ApplyInt<Alias> works fine. 然后ApplyInt<Alias>可以正常工作。

To recap, in ApplyInt<Alias> is treated as a template template argument but not in Matched<Alias<int>> . 回顾一下, ApplyInt<Alias>被视为模板模板参数,而Matched<Alias<int>> I find this a little stupid because I think about type aliases as functions on types and I would like to work with them. 我觉得这有点愚蠢,因为我认为类型别名是类型上的函数,我想与它们一起工作。 Right now, type aliases are treated as second class citizens compared to types and this makes hard to work with them in a generic way, such as composing or transforming them. 目前,与类型相比,类型别名被视为二等公民,这使得很难以通用方式使用它们,例如编写或转换它们。

Possible ways out: 可能的解决方法:

1.Change deduction rules such that type alias is detected as template template argument. 1.更改推导规则,以便将类型别名检测为模板模板参数。 This would make Matched<Alias>==true . 这将使Matched<Alias>==true

2.Allow usage of using in template declaration like this: 2.允许在模板声明中using use,如下所示:

template<template<typename> using T, typename T>
bool Matched<F<T>> = true;

Question: 题:

Is this behavior intentional? 这种行为是故意的吗? Is this an oversight? 这是疏忽吗? Was this noticed and will it be fixed in a future version in c++? 是否注意到了这一点,并将在c ++的将来版本中对其进行修复吗?


As a side note: The similar problem is with variable templates. 附带说明:变量模板也存在类似问题。 Why cannot we write? 为什么我们不能写?

template <template<typename> auto Var>
auto VarForInt = Var<int>;

Edit(after accepting the answer): 编辑(接受答案后):

I'm really puzzled by the type deduction. 我真的对类型推导感到困惑。 When we store a type alias in a helper class 当我们在助手类中存储类型别名时

template<template<typename> typename F>
struct Helper{};

and we have a function 我们有一个功能

template<template<typename> typename F>
void foo(Helper<F>){}

We can call foo(Helper<Alias>{}) . 我们可以调用foo(Helper<Alias>{}) Isn't Alias "deduced" in the function call? 函数调用中不是“推论” Alias吗? Or this is not called type deduction? 还是这不称为类型推演?

Yes, that is intentional. 是的,这是故意的。 Alias templates are indeed, as you said, somewhat of a "second class citizen". 正如您所说,别名模板确实有点像“二等公民”。 To start with, alias templates cannot be specialized, that's a real big hint right there. 首先,别名模板不能专门化,这确实是一个很大的提示。

Now, their "lower grade" as evident in your example is all about [temp.alias]/2 : 现在,在您的示例中显而易见的是,它们的“较低等级”与[temp.alias] / 2有关

When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the type-id of the alias template. 模板id是指一个别名模板的专业化,它相当于通过其模板参数在别名模板的类型-ID 模板参数替代所获得的相关的类型。 [ Note: An alias template name is never deduced. [注意:不会推导别名模板名称。 — end note ] —尾注]

The above means, that when you write Matched<Alias<int>> , since Alias<int> refers to a specialization of the alias template, it's equivalent to directly writing Matched<std::tuple<int,int>> . 上面的意思是,当您编写Matched<Alias<int>> ,由于Alias<int>是指别名模板的特殊化,因此等效于直接编写Matched<std::tuple<int,int>> And it's quite obvious why that doesn't match the specialized variable template. 很明显为什么不匹配专门的变量模板。

It's not an oversight, nor is it going to be fixed. 这不是疏忽,也不是固定的。 Alias templates are there to provide a shorthand for more complex template expressions. 别名模板在那里提供了更复杂的模板表达式的简写。 And you wouldn't want the wrong overload to be called, or the wrong template specialization instantiated, because you used a shorthand instead of the whole complex expression. 而且,您不会希望调用错误的重载,也不希望实例化错误的模板特化,因为您使用的是速记而不是整个复杂的表达式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM