参考模板c++

refering to Templates c++

考虑模板Class 我们什么时候必须显式引用模板,以及编译器什么时候 "understands that we meant it"

考虑到以下情况:

1) 函数 return 价值和争论

2) 函数内的变量声明

3) 命名空间 SomeClass<T>::SomeClass::

有什么规定吗?我看到有时使用的是:

SomeClass

有时:SomeClass<T>

我没听懂规则

Class 模板参数可能 在 class 的实现中被省略,其中它们隐式地将适当的模板说明符添加到 class 并且在引用非依赖基 class 时(如 "does not reuse any template arguments" 中的非依赖)。例如:

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!
};

标准描述了[temp.local]中的所有场景:

  1. Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected-class-name can be used as a template-name or a type-name. When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type-specifier of a friend class template declaration, it refers to the class template itself. Otherwise, it is equivalent to the template-name followed by the template-parameters of the class template enclosed in <>.

  2. Within the scope of a class template specialization or partial specialization, when the injected-class-name is used as a type-name, it is equivalent to the template-name followed by the template-arguments of the classtemplate specialization or partial specialization enclosed in <>.

[ Example:

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
  };
};

—end example ]

这仅在 class 模板内部有效(即注入-class-名称的范围),并且仅当从相应范围访问该名称时才有效:

When the normal name of the template (i.e., the name from the enclosing scope, not the injected-class-name) is used, it always refers to the class template itself and not a specialization of the template. [ Example:

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
};

—end example ]

对于基 classes,基不相关:

A lookup that finds an injected-class-name (10.2) can result in an ambiguity in certain cases (for example, if it is found in more than one base class). If all of the injected-class-names that are found refer to specializations of the same class template, and if the name is used as a template-name, the reference refers to the class template itself and not a specialization thereof, and is not ambiguous. [ Example:

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
};

—end example ]

我们可以稍微修改示例以显示有效内容:

template <class T> struct Base { };
template <class T> struct Derived: Base<char> {
  typename Derived::Base b;             // Ok: b refers to Base<char>
};