Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 迭代C++;可变模板_C++_Templates_Variadic - Fatal编程技术网

C++ 迭代C++;可变模板

C++ 迭代C++;可变模板,c++,templates,variadic,C++,Templates,Variadic,我有以下资料: template<typename FIRST, typename SECOND> Sender *createSenderChain() { return new FIRST(new SECOND()); } 模板 发送方*createSenderChain(){ 返回新的第一个(新的第二个()); } 是否可以使模板可变: template<typename FIRST, typename ...Args> Sender *createSe

我有以下资料:

template<typename FIRST, typename SECOND>
Sender *createSenderChain() {
    return new FIRST(new SECOND());
}
模板
发送方*createSenderChain(){
返回新的第一个(新的第二个());
}
是否可以使模板可变:

template<typename FIRST, typename ...Args>
Sender *createSenderChain() {
    return new FIRST(new SECOND(new THIRD(new ...))  <-- This is the pattern I want, 
                                                         but how should it be done 
                                                         using the args list?
}
模板
发送方*createSenderChain(){
返回新的第一个(新的第二个)(新的第三个(新的…)您可以对此使用递归!

猜测您对
发送者的定义

struct Sender { ~Sender() {} };

struct A : Sender { A(Sender* = nullptr) {} };
struct B : Sender { B(Sender* = nullptr) {} };
struct C : Sender { C(Sender* = nullptr) {} };


// Base case
template <typename T>
Sender* createSenderChain()
{
    return new T();
}

// Recursive case
template <typename T1, typename T2, typename ...Ts>
Sender* createSenderChain()
{
    return new T1(createSenderChain<T2, Ts...>());
}

int main()
{
    auto ptr = createSenderChain<A, B, C>();
}
struct Sender{~Sender(){};
结构A:发送方{A(发送方*=nullptr){};
结构B:发送方{B(发送方*=nullptr){};
结构C:发送方{C(发送方*=nullptr){};
//基本情况
模板
发送方*createSenderChain()
{
返回新的T();
}
//递归案例
模板
发送方*createSenderChain()
{
返回新的T1(createSenderChain());
}
int main()
{

auto ptr=createSenderChain)您可以使用不同的模板参数调用相同的可变模板函数:

template<typename FIRST, typename SECOND, typename ...Args>
Sender* createSenderChain() {
    return new typename FIRST(createSenderChain<SECOND, Args...>());
}

template<typename FIRST>
Sender* createSenderChain() {
    return new typename FIRST();
}
模板
发送方*createSenderChain(){
首先返回新的typename(createSenderChain());
}
模板
发送方*createSenderChain(){
首先返回新的typename();
}

在第一个函数中,我们不仅明确地说明了<>代码>类型名> ,而且也明确了<代码>类型名第二个/>代码,以避免将这个实现与 CurresteNeDeloSnc/Cuth>调用匹配,因为变量部分可以与空类型列表相匹配。

< P>因为您的问题没有指定使用C++的哪一个变体,这个解决方案u这意味着它可以避免递归

我们通过二进制折叠来解析函数的组合。为此,我们首先需要将函数对象转换为可通过二进制操作组合的对象:

template<class F>
struct compose_t {
  F f;
  template<class Lhs, class Rhs>
  auto operator*( compose_t<Lhs> lhs, compose_t<Rhs> rhs ) {
    auto r =
      [lhs = std::move(lhs).f, rhs = std::move(rhs).f](auto&&...args)
      ->decltype(auto)
      { return lhs(rhs(decltype(args)(args)...)); }
    return compose_t<decltype(r)>{ std::move(r) };
  }
  template<class...Args>
  decltype(auto) operator()(Args&&...args){
    return f(std::forward<Args>(args)...);
  }
};
template<class F>
compose_t<F> compose(F f) { return {std::forward<F>(f)}; }
maker
返回一个函数对象,该对象在稍后提供的一组参数上表示calling
make_unique
。我可以使用原始指针来执行此操作,但我拒绝

template<typename ...Args>
std::unique_ptr<Sender> createSenderChain() {
  return (compose( maker<Args>() ) * ...)();
}
模板
std::unique_ptr createSenderChain(){
返回(编写(maker())*…)();
}

完成了。请注意,我使用了
unique\u ptr
s而不是
Sender*
s,因为我拒绝提供您不应该使用的垃圾代码。

顺便说一句,我更喜欢
std::unique\u ptr
std::shared\u ptr
而不是原始
新的
。我的演示有三个内存泄漏!
template<typename ...Args>
std::unique_ptr<Sender> createSenderChain() {
  return (compose( maker<Args>() ) * ...)();
}