考虑模板类 什么时候我们必须明确地引用模板,以及编译器“理解我们的意思”
考虑以下事件:
1)功能返回值& arguements
2)函数内的变量声明
3)名称空间SomeClass<T>::
与SomeClass::
有规则吗?我有时看到使用的是:
SomeClass
有时:SomeClass<T>
我没有得到规则
答案 0 :(得分:3)
类模板参数可以在该类的实现中忽略 ,其中它们隐式地向类中添加适当的模板说明符,并且在引用非依赖的基类时(非依赖类) in&#34;不重用任何模板参数&#34;)。例如:
template<typename T, typename U>
class C { /* here C is the same as C<T, U> */ };
template<typename T>
class C<void, T> { /* here C is the same as C<void, T> */ };
template<>
class C<void, void> { /* here C is the same as C<void, void> */ };
template<typename> struct Base { };
struct DerivedA : Base<void>
{ /* here Base is the same as Base<void> */ };
template<typename T>
struct DerivedB : Base<T>
{ /* here Base is invalid, since Base<T> depends on a template argument */ };
如果可以从参数推断出函数模板,则可以省略其模板参数:
template<typename T>
void f(T f);
f(3); // equivalent to f<int>(3) if no other overload exists
此外,还有默认模板参数,这些参数会导致something really funky:
template<typename T = void>
class D
{
// Here D is D<T>, but D<> is D<void> instead!
};
答案 1 :(得分:0)
该标准描述了[temp.local]中的所有方案:
与普通(非模板)类一样,类模板具有注入类名(第9条)。注入类名可以用作 模板名称或类型名称。与它一起使用时 template-argument-list ,作为模板参数的模板参数,或作为模板参数的最终标识符 朋友类模板声明的 elaborated-type-specifier ,它指的是类模板本身。 否则,相当于 template-name 后跟类的模板参数
<>
中附带的模板。- 醇>
在类模板特化或部分特化的范围内,当inject-class-name用作类型名称时, 它相当于后面跟着的模板名 classtemplate专门化或部分的模板参数
<>
中包含的专业化。[示例:
template<template<class> class T> class A { }; template<class T> class Y; template<> class Y<int> { Y* p; // meaning Y<int> Y<char>* q; // meaning Y<char> A<Y>* a; // meaning A<::Y> class B { template<class> friend class Y; // meaning ::Y }; };
- 示例]
这仅适用于类模板(即inject-name-name的范围),并且只有从相应的范围访问该名称时才会起作用:
当模板的正常名称(即,来自的名称) 它总是使用封闭范围,而不是注入类名称) 是指类模板本身而不是专门化的 模板。 [示例:
template<class T> class X { X* p; // meaning X<T> X<T>* p2; X<int>* p3; ::X* p4; // error: missing template argument list // ::X does not refer to the injected-class-name };
- 示例]
对于基类,基类不依赖:
查找注入类名称(10.2)的查找可能会导致 在某些情况下的歧义(例如,如果发现超过 一个基类)。如果找到所有注入的类名 引用相同类模板的特化,如果名称 用作模板名称,引用引用该类 模板本身而不是专业化,而不是 暧昧。 [示例:
template <class T> struct Base { }; template <class T> struct Derived: Base<int>, Base<char> { typename Derived::Base b; // error: ambiguous typename Derived::Base<double> d; // OK };
- 示例]
我们可以稍微修改示例以显示有效的内容:
template <class T> struct Base { };
template <class T> struct Derived: Base<char> {
typename Derived::Base b; // Ok: b refers to Base<char>
};