C++ 从可变模板构造类

C++ 从可变模板构造类,c++,templates,variadic-templates,C++,Templates,Variadic Templates,我试图创建一个名为Sink的类,它将创建一个指向您传入的类的指针,这是在RAII中封装一个api 在这段代码的完整版本中,自定义类也从另一个类继承,并且有静态资产来检查这一点。指针也被传递到api 但为了简单起见,我删除了这个 这是我从中得到的错误 函数“int main()”中的: 43:30:错误:对“Sink::Sink(int)”的调用没有匹配的函数 43:30:注:候选人为: 10:5:注意:Sink::Sink(Args&&…[带有CustomSink=OneArg;Args={}]

我试图创建一个名为
Sink
的类,它将创建一个指向您传入的类的指针,这是在RAII中封装一个api

在这段代码的完整版本中,自定义类也从另一个类继承,并且有静态资产来检查这一点。指针也被传递到api

但为了简单起见,我删除了这个

这是我从中得到的错误

函数“int main()”中的
:
43:30:错误:对“Sink::Sink(int)”的调用没有匹配的函数
43:30:注:候选人为:
10:5:注意:Sink::Sink(Args&&…[带有CustomSink=OneArg;Args={}]
10:5:注意:候选者需要0个参数,提供1个
代码:

#include <string>
#include <iostream>
#include <memory>
#include <utility>

template<typename CustomSink, typename... Args>
class Sink
{
public:
    Sink(Args&&... args)
    {        
       _ptr = std::make_unique<CustomSink>(std::forward<Args>(args)...);        
    }
    ~Sink() 
    {
    }
private:
    std::unique_ptr<CustomSink> _ptr;
};


//////////////////////////////////////////////////////////////////////
class NoArg
{
public:
    NoArg() {};
    ~NoArg() {};
};

class OneArg
{
public:
    OneArg(int a) {
        std::cout << a << '\n';
    };
    ~OneArg() {};
};
//////////////////////////////////////////////////////////////////////


int main(){
    Sink<NoArg> noArgSink;   
    Sink<OneArg> oneArgSink(5);  

    return 0;
}
#包括
#包括
#包括
#包括
模板
班级水槽
{
公众:
接收器(Args&…Args)
{        
_ptr=std::make_unique(std::forward(args)…);
}
~Sink()
{
}
私人:
std::唯一的\u ptr\u ptr;
};
//////////////////////////////////////////////////////////////////////
诺格级
{
公众:
NoArg(){};
~NoArg(){};
};
第一类arg
{
公众:
OneArg(整数a){

std::cout构造函数的模板参数应该从类移动到模板构造函数:

template<typename CustomSink>
class Sink
{
public:
    template <typename... Args>
    Sink(Args&&... args)
    {        
       _ptr = std::make_unique<CustomSink>(std::forward<Args>(args)...);        
    }
private:
    std::unique_ptr<CustomSink> _ptr;
};
模板
班级水槽
{
公众:
模板
接收器(Args&…Args)
{        
_ptr=std::make_unique(std::forward(args)…);
}
私人:
std::唯一的\u ptr\u ptr;
};

根据您的设计,您必须编写:

Sink<OneArg, int> oneArgSink(5);
Sink-oneArgSink(5);

实际上,构造函数参数的数量和类型是由模板的可变部分(
typename…Args
)决定的。但这部分附加到类,而不是构造函数。所以在实例化模板时必须指定它


否则,如果您想尊重您的实例化并让编译器确定模板参数,您必须将模板的可变部分移动到构造函数(请参阅或)

您这里的问题是模板类型
Args
的位置。现在您在类tempalte so中有
Args

Sink<OneArg> oneArgSink(5);

现在,构造函数将推导传递给它的参数,而不必在声明类时指定它。

声明类
Sink
的方式意味着您需要在模板实例化时指定
Args…

这意味着,如果您声明
Sink
,则实际上是在将
Args…
设为空,并且构造函数不需要任何参数。这就是编译器抱怨将参数传递给构造函数的原因

在构造函数中只需要变量模板,这样你甚至可以容纳具有多个不同参数的构造函数的类

template<typename CustomSink>
class Sink
{
public:
    template<typename... Args>
    Sink(Args&&... args)
    {
        _ptr = std::make_unique<CustomSink>(std::forward<Args>(args)...);
    }
    ~Sink()
    {
    }
private:
    std::unique_ptr<CustomSink> _ptr;
};
模板
班级水槽
{
公众:
模板
接收器(Args&…Args)
{
_ptr=std::make_unique(std::forward(args)…);
}
~Sink()
{
}
私人:
std::唯一的\u ptr\u ptr;
};
template<typename... Args>
Sink(Args&&... args)
{        
   _ptr = std::make_unique<CustomSink>(std::forward<Args>(args)...);        
}
template<typename CustomSink>
class Sink
{
public:
    template<typename... Args>
    Sink(Args&&... args)
    {
        _ptr = std::make_unique<CustomSink>(std::forward<Args>(args)...);
    }
    ~Sink()
    {
    }
private:
    std::unique_ptr<CustomSink> _ptr;
};