我注意到在使用类型别名时模板模板扣除期间存在一些不一致。特别是类型别名可以用作模板模板参数,但不能推断为一个。
我们将使用Matched<Type>
来查看Type
是否是模板类型的实例。
template <typename T>
bool Matched = false;
template <template <typename> typename F, typename T>
bool Matched<F<T>> = true;
现在定义一个类型别名
template<typename T>
using Alias = std::tuple<T,T>;
我的问题是Matched<Alias<int>>==false
。但是Alias
可以用作模板模板参数,例如:
template<template<typename> typename F>
using ApplyInt = F<int>;
然后ApplyInt<Alias>
正常工作。
总结一下,ApplyInt<Alias>
中的Matched<Alias<int>>
被视为模板模板参数,但不在Matched<Alias>==true
中。我发现这有点愚蠢,因为我认为类型别名作为类型的函数,我想与它们一起工作。现在,与类型相比,类型别名被视为二等公民,这使得难以以通用方式使用它们,例如组合或转换它们。
1.更改扣除规则,以便将类型别名检测为模板模板参数。这将使using
。
2.在模板声明中使用template<template<typename> using T, typename T>
bool Matched<F<T>> = true;
,如下所示:
template <template<typename> auto Var>
auto VarForInt = Var<int>;
这种行为是故意的吗?这是疏忽吗?这是否被注意到并将在c ++的未来版本中修复?
作为旁注:类似的问题是变量模板。为什么我们不能写?
template<template<typename> typename F>
struct Helper{};
编辑(接受答案后):
我对类型演绎感到困惑。当我们在辅助类中存储类型别名
时template<template<typename> typename F>
void foo(Helper<F>){}
我们有一个功能
foo(Helper<Alias>{})
我们可以致电Alias
。 Isn&#t; t onNavigationStateChange={(prevState, newState) => {
// your code to determine screen
})
&#34;推断&#34;在函数调用中?或者这不叫做类型扣除?
答案 0 :(得分:4)
是的,那是故意的。正如你所说,别名模板确实是一个二等公民&#34;。首先,别名模板不能专门化,这是一个真正的大提示。
现在,他们的等级较低&#34;在你的例子中显而易见的是关于[temp.alias]/2:
当 template-id 引用别名的特化时 模板,它相当于获得的关联类型 将 template-arguments 替换为 template-parameters 在别名模板的 type-id 中。 [注意:别名模板名称 永远不会推断出来。 - 结束说明]
以上意思是,当您撰写#!python2
x = [[1, ["cat", "dog"]], [2, ["dog", "mouse", "elephant"]], [3, ["mouse", "giraffe"]]]
new_lst = []
for sublst in x:
for subsublst in sublst[1]:
if not any(subsublst in sublst for sublst in new_lst):
new_lst.append([subsublst]) # nested list
# new_lst.append(subsublst) # a list of strings
print new_lst
'''
[['cat'], ['dog'], ['mouse'], ['elephant'], ['giraffe']]
'''
时,由于Matched<Alias<int>>
指的是别名模板的特化,它等同于直接写Alias<int>
1}}。并且很明显为什么它与专用变量模板不匹配。
这不是疏忽,也不会被修复。别名模板用于提供更复杂的模板表达式的简写。并且您不希望调用错误的重载,或者实例化错误的模板特化,因为您使用了简写而不是整个复杂表达式。