参考模板c ++

时间:2015-02-05 13:12:07

标签: c++ templates

考虑模板类 什么时候我们必须明确地引用模板,以及编译器“理解我们的意思”

考虑以下事件:

1)功能返回值& arguements

2)函数内的变量声明

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

有规则吗?我有时看到使用的是:

SomeClass

有时:SomeClass<T>

我没有得到规则

2 个答案:

答案 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]中的所有方案:

  
      
  1. 与普通(非模板)类一样,类模板具有注入类名(第9条)。注入类名可以用作   模板名称类型名称。与它一起使用时    template-argument-list ,作为模板参数模板参数,或作为模板参数的最终标识符   朋友类模板声明的 elaborated-type-specifier ,它指的是类模板本身。 否则,相当于    template-name 后跟类的模板参数   <>中附带的模板。

  2.   
  3. 在类模板特化或部分特化的范围内,当inject-class-name用作类型名称时,   它相当于后面跟着的模板名   classtemplate专门化或部分的模板参数   <>中包含的专业化。

  4.         

    [示例:

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