2017-10-06 87 views
8

考虑这样一个例子:能够保证所有的模板,模板参数调用用户提供扣除引导

#include <type_traits> 
#include <string> 

template <template <class> class TT> //#1 
struct Foo { 
    static void foo() { 
     static_assert(std::is_same_v<decltype(TT("abc")), TT<std::string>>); 
    } 
}; 

template <class T> 
struct Bar { 
    Bar(T) {} 
}; 

template <class T> 
Bar(T) -> Bar<std::string>; //#2 

int main() { 
    Foo<Bar>::foo(); 
} 

[clang]以及[gcc]似乎都使用用户提供的扣除指南(#2)推导模板的模板参数时模板参数(#1)。它是符合标准的功能吗?

回答

4

是的,这符合标准。

根据[dcl.type.simple]/2

类型说明符的形式typename选择的嵌套名称说明符选择模板名称为推导的类类型的占位符([dcl.type.class.deduct])。 模板名称应命名不是注入类名的类模板。

而且[temp.param]/3

类型参数其标识符不遵循省略号限定其标识符是一个的typedef名(若无template声明)或模板名称(如果在template中声明)在模板声明的范围内。

TTtemplate声明的类型参数,这使得它成为模板名称并且因此对于一个推导的类类型的占位符。所有通常的规则都适用。

+0

我真的期待这个答案,但是如果碰巧是错误的,那么我会把它拿回来;) –

+0

作为一个小问题:你认为自动演绎指南不应该被应用吗? –

+0

@ W.F。好吧,我彻底翻转了答案:) – Barry