模板占位符未在成员的返回类型中定义,仍然可以正常工作

Template placeholder not defined in return type of member, still works fine?

本文关键字:常工作 工作 占位符 成员 定义 返回类型      更新时间:2023-10-16

在下面的代码段中,我省略了Assignment运算符(operator=)的返回类型中的模板参数占位符。在我是否指定了模板参数的两种情况下,代码都运行得很好,只是想知道为什么?

感谢

#include <iostream>
using std::cout; using std::endl;
class Ref
{
    int _ref_counter;
public:
    Ref() : _ref_counter(0)     {}
    void upRef() { _ref_counter++; }
    int downRef() { return --_ref_counter; }
};
template <typename T1> class SmartPointer
{
    T1* _ptr;
    Ref *_ref;
public:
    SmartPointer() : _ptr(0)
    {
        _ref = new Ref();
        _ref->upRef();
    }
    SmartPointer(T1* ptr): _ptr(ptr)
    {
        _ref = new Ref();
        _ref->upRef();
    }
    SmartPointer(const SmartPointer &sp): _ptr(sp._ptr), _ref(sp._ref)
    {
    {
        _ref->upRef();
    }
//      SmartPointer<T1>& operator= (const SmartPointer &sp)
    SmartPointer& operator= (const SmartPointer &sp)
    {
        //Always check self assignment
        if(this != &sp)
        {
            //Lose the existing smartpointer info
            if(0 == _ref->downRef())
            {
                delete _ptr;
                delete _ref;
            }
            _ptr = sp._ptr;
            _ref = sp._ref;
            _ref->upRef();
        }
        return *this;
    }
    ~SmartPointer()
    {
        if(0 == _ref->downRef())
        {
            delete _ptr;
            delete _ref;
        }
    }
    T1& operator* () { return *_ptr; }
    T1* operator-> () { return _ptr; }
};
class Lock
{
public:
    void somefuntion()
    {
        cout << "somefunction called ! " << endl;
    }
    ~Lock()
    {
        cout << "Destructor Lock called !" << endl;
    }
};
int main()
{
    SmartPointer<Lock> pMemLock(new Lock());
    pMemLock->somefuntion();
    {
        SmartPointer<Lock> pMemLock1(pMemLock);
    }
    SmartPointer<Lock> pMemLock2;
    pMemLock2 = pMemLock;
    pMemLock2->somefuntion();
}

来自标准[n3690:14.6.1/1]:

与普通(非模板)类一样,类模板具有注入类名(第9条)。注入的类名可以用作模板名称或类型名称。当它与模板参数列表,作为模板的模板参数模板参数,或作为详细类型中的最终标识符友元类模板声明的说明符,它引用类模板本身。否则,它相当于后跟类的模板参数的模板名称包含在<>中的模板。

这就是所谓的注入类名。在模板X<T>中,名称X等效于X<T>。这里有一个有趣的例子:

template<template<class T> class X>
class Y
{
};
template<class T>
class X;
{
    Y<X> mem; //won't compile, because X is not a template, but is equivalent to X<T>, which is a type.
};

另请参阅:注入的类名不明确不是错误