bar*_*top 3 c++ language-lawyer
在回答其中一个问题时,我遇到了这样的代码:
template<class T, class... Ts> void foo();
template <class T, class T::value_type>
void foo() { }
Run Code Online (Sandbox Code Playgroud)
它被呈现为代码专用foo
模板功能,这是不对的,但这不是我的问题.我想知道为什么编译器允许这样的构造:class T::value_type
在模板参数中.我的意思是,这显然是错误的,我无法想出范围运算符可能是参数名称(模板或函数)的一部分的任何情况.所以我有两个问题:
正如评论中所提到的,它是一个精心设计的类型说明符.最佳解释一个例子:
int main() {
struct foo {}; // ok
int foo = 0; // ok
int test = foo; // ok, refers to variable 'foo'
foo a; // error, 'foo' refers to variable
struct foo b; // ok, 'struct' means that name lookup searches for classes only
}
Run Code Online (Sandbox Code Playgroud)
实质上,您可以将它们(struct/class
,enum
)视为更受限制的typename
,因为它们分别只允许类或枚举.另请注意typename
原始示例中允许的内容!
template<class T, class... Ts> void foo();
template <class T, typename T::value_type> // Ok, value_type needs to be a type
// ^^^^^^^^^^^^^^^^^^^^^^^ it's a non-type template parameter
void foo() { }
Run Code Online (Sandbox Code Playgroud)
当你有一个具有相同名称的类型和变量时需要它,或者当你有一个从属名称时指定它是什么(即class T::value_type
,value_type
是一个类,没有class
之前的,它将是一个值.通常, a typename
被使用.)
我不能提出范围运算符可能是参数名称的一部分的任何情况
你在这里只考虑类型模板参数; 非类型模板参数可以很好地使用范围运算符来命名类型.