C++ 模板重新声明中的模板参数太多

C++ 模板重新声明中的模板参数太多,c++,templates,clang,variadic,C++,Templates,Clang,Variadic,你好:-) 我有以下代码:目标是返回一个函数,它大致上是其他函数的总和。并了解可变模板 #include <iostream> template <typename F> struct FSum { FSum(F f) : f_(f) {} ; int operator()() { return f_() ; } F f_ ; } ; template <typename F1, typename F2, typen

你好:-)

我有以下代码:目标是返回一个函数,它大致上是其他函数的总和。并了解可变模板

#include <iostream>

template <typename F>
struct FSum {
    FSum(F f) : f_(f) {} ;
    int operator()() {
        return f_() ;
    }
    F f_ ;
} ;
template <typename F1, typename F2, typename... Frest>
struct FSum {
    FSum(F1 f1, F2 f2, Frest... frest) {
        f_ = f1 ;
        frest_ = FSum<F2, Frest...>(f2, frest...) ;
    }
    int operator()() {
        return f_() + frest_() ;
    }
    F1 f_ ;
    FSum<F2, Frest...> frest_ ;
} ;

struct F1 {
    int operator() () { return 1 ; } ; 
} ;
struct F2 {
    int operator() () { return 2 ; } ; 
} ;
struct F3 {
    int operator() () { return 3 ; } ; 
} ;

int main() {
    F1 f1 ; 
    F2 f2 ;
    F3 f3 ;
    FSum<F1, F2, F3> fsum = FSum<F1, F2, F3>(f1, f2, f3) ;
    std::cout << fsum() << std::endl ;
}
#包括
模板
结构FSum{
FSum(F):F_F(F){};
int运算符()(){
返回f_();
}
F_;
} ;
模板
结构FSum{
FSum(F1、F2、Frest…Frest){
f_u=f1;
frest_ufsum(f2,frest…);
}
int运算符()(){
返回f_u()+frest_u();
}
F1 f_2;;
弗雷斯特;
} ;
结构F1{
int运算符(){return 1;};
} ;
结构F2{
int运算符(){return 2;};
} ;
结构F3{
int运算符(){return 3;};
} ;
int main(){
F1;
F2 F2;
F3 F3;
FSum FSum=FSum(f1,f2,f3);

std::cout您不能有两个具有不同模板参数的类型。您正在尝试将类用作函数(其中可以共享多个定义/名称)但是类和结构不是这样工作的。您需要重命名其中一个结构或将它们合并为一个结构。

编译器正在抱怨,因为您要两次重新定义同一模板结构,而您需要的是部分模板专用化。请参阅下面示例中的语法

至于让变量模板做你想做的事情的逻辑,从递归的角度考虑它是有帮助的。下面的代码就是你想做的:

#include <iostream>

using namespace std;

// stops "recursion" when it is called with no parameters
template <typename... Frest> struct FSum {
    int operator()() {
        return 0;
    }
};

// Partial Specialization of FSum above
// called when there is at least one template parameter
template <typename F, typename... Frest>
struct FSum<F, Frest...> {

    // "recursion" in the construction of frest_
    FSum(F f, Frest... frest) : f_(f), frest_(frest...) {}

    // "recursion" in the calling of frest()
    int operator()() {
        return f_() + frest_();
    }

    F f_;
    FSum<Frest...> frest_;
};


struct F1 {
    int operator()() { return 1; }
};

struct F2 {
    int operator()() { return 2; }
};

struct F3 {
    int operator()() { return 3; }
};

int main() {
    F1 f1;
    F2 f2;
    F3 f3;
    FSum<F1, F2, F3> fsum(f1, f2, f3);
    cout << fsum() << endl;
}
#包括
使用名称空间std;
//在无参数调用时停止“递归”
模板结构{
int运算符()(){
返回0;
}
};
//上述FSum的部分特化
//当至少有一个模板参数时调用
模板
结构FSum{
//frest结构中的“递归”_
FSum(F,Frest…Frest):F(F),Frest(Frest…{}
//frest()调用中的“递归”
int运算符()(){
返回f_u()+frest_u();
}
F_;
弗雷斯特;
};
结构F1{
int运算符(){return 1;}
};
结构F2{
int运算符(){return 2;}
};
结构F3{
int运算符(){return 3;}
};
int main(){
F1;
F2 F2;
F3 F3;
FSum FSum(f1,f2,f3);

请注意,还会有一个运行时嵌套的“递归”——类似于调用堆栈,您需要支付常规运行时递归的所有费用!作为回报,f_()+frest_();其中frest_()将调用对FSum操作符()的嵌套调用,该调用将调用另一个FSum操作符()的剥离版本依此类推,直到它达到递归基础。我不知道编译器是否能够将此调用堆栈展开为运算符的平面序列()求值。你是对的@barney.“函数调用序列”的运行时成本与运行时递归相当。