模板类中的可变模板函数特化

问题描述

我正在尝试实现一个自己的 SmartPointer 类,在最初的工作版本之后,我开始改进代码,现在面临一个我无法解决的问题。

这是第一个版本:

template<class T>
class SmartPointer
{
private:
    T* ptr;
public:
    explicit SmartPointer(T* p = nullptr):ptr(p){}
    ~SmartPointer(){delete(ptr);}
    T& operator*(){return *ptr;}
    T* operator->(){return ptr;}
};

我的问题是我必须调用它两次指定这将是例如。一个“int”类型的指针:

SmartPointer<int> intSP(new int());

所以我尝试在 SmartPointer 类的构造函数中创建一个模板构造函数,将其更改为:

template<typename... Args>
explicit SmartPointer(Args... args):ptr(new T(args...)){};

在我提供至少一个参数之前,这一切正常。但是当没有提供参数时,整个类就开始不工作了。 (当我从它创建一个实例并尝试分配一个值时,它抛出以下错误:“分配只读位置'* intSP'”。

所以我试图进一步复杂化,在参数包的大小上使用 enable_if,不幸的是结果与前一种情况相同。由于某种原因, enable_if 似乎根本没有做任何事情:

    template<typename... Args,typename = typename std::enable_if<(sizeof...(Args)>0u)>::type>
    explicit SmartPointer(Args... args):ptr(new T(args...)){
        cout << "constructor with arguments" << endl;
    };
    template<typename... Args,typename = typename std::enable_if<(sizeof...(Args)==0u)>::type>
    explicit SmartPointer():ptr(new T()){
        cout << "constructor without args" << endl;
    };

最后是完整的代码,有一些概述:

#include <iostream>

using namespace std;
#define var2str(var) #var
template<class T>
class SmartPointer
{
private:
    T* ptr;
public:
    template<typename... Args,typename = typename std::enable_if<(sizeof...(Args)==0u)>::type>
    explicit SmartPointer():ptr(new T()){
        cout << "constructor without arguments" << endl;
    };
    ~SmartPointer(){delete(ptr);}
    T& operator*(){return *ptr;}
    T* operator->(){return ptr;}
};

int main(int,char**) {
    SmartPointer<int> intSP(5);//new int());

    cin>>*intSP;
    cout << *intSP << " stored in "<< var2str(intSP) << endl;
}

解决方法

我想您的问题(只有一个构造函数)是由“烦人的解析”(here 对“最烦人的解析问题”的描述,该问题的更壮观的版本)引起的。

我的意思是...如果你写

Cmd + shift + 4

编译器将其解释为函数声明。

如果你想初始化一个没有参数的变量,你可以使用方括号

SmartPointer<int> intSP();

或者没有括号

SmartPointer<int> intSP{};

我想下面的例子应该很有用

SmartPointer<int> intSP;