Templates 如何编写同时包含变量和参数的泛型函子类?
出于数学目的,我想编写一个泛型函子类,用变量和参数包装简单的数学方程。想象一条简单的抛物线:Templates 如何编写同时包含变量和参数的泛型函子类?,templates,generics,c++11,tuples,variadic,Templates,Generics,C++11,Tuples,Variadic,出于数学目的,我想编写一个泛型函子类,用变量和参数包装简单的数学方程。想象一条简单的抛物线: y=f(x;a,b,c)=a*x*x+b*x+c 这里a、b和c是一条抛物线的一次参数设置。然后 纵坐标值y是通过提供 变量x。我已经用variadic编写了一个简单的gen_func类 模板与std::tuple结合使用,用于保存参数和 变量的可变参数包。这门课的骨架是 发现于 我是新的c++11标准的新手,我知道写代码是正确的 使用可变模板的代码是一件非常复杂的事情 出于某些目的,我想通过引用
y=f(x;a,b,c)=a*x*x+b*x+c
这里a、b和c是一条抛物线的一次参数设置。然后
纵坐标值y是通过提供
变量x。我已经用variadic编写了一个简单的gen_func类
模板与std::tuple结合使用,用于保存参数和
变量的可变参数包。这门课的骨架是
发现于
我是新的c++11标准的新手,我知道写代码是正确的
使用可变模板的代码是一件非常复杂的事情
出于某些目的,我想通过引用调用来更改变量。但在这里,编译器GCC4.7确实有问题。为了简单起见,我用一个简单的函数更改测试了代码。它的唯一目的是改变传递的第一个变量的值。下面是一个简单程序的代码:
#include <tuple>
#include <iostream>
#include <functional>
#include<utility>
using namespace std;
// Compile with : g++ -o X.bin -Wall -pedantic -std=c++11 X.cpp
// Stuff for compile-time recursive parameter pack expansion:
namespace generic
{
template <std::size_t... Ts>
struct index_sequence {};
template <std::size_t N, std::size_t... Ts>
struct sequence_generator : sequence_generator<N - 1, N - 1, Ts...> {};
template <std::size_t... Ts>
struct sequence_generator<0, Ts...> : index_sequence<Ts...> {};
template< typename ReturnType , typename... Args > using generic_function_pointer = ReturnType (*) ( Args... args ) ;
}
// The generic Function wrapper:
template < typename R , class F , typename... Ps>
class gen_func
{
public:
// Constructor
gen_func(F&& f,Ps&&...parms){
func = forward<F>(f);
parameters=make_tuple(forward<Ps>(parms)...);
}
// execute-Function for public call:
template<typename... Vars>
R execute(Vars&&... vars) {
return f_decon<Vars... , Ps...>( forward<Vars>(vars)... , parameters );
}
//
private:
// "Deconvolution Function"
template<typename... Vars , typename... Ts >
R f_decon( Vars&&... vars , tuple<Ts...>& tup ){
return f_proxy<Vars...,Ps...>( forward<Vars>(vars)... , tup , generic::sequence_generator<sizeof...(Ts)>{} );
}
// "Proxy-Function" calling the wrapped Function func:
template<typename... Vars , typename... Ts , size_t... Is>
R f_proxy( Vars&&... vars , tuple<Ts...>& tup , generic::index_sequence<Is...> ){
return func( forward<Vars>(vars)... , get<Is>(tup)... );
}
// The wrapped Function f
F func;
// The tuple holding optional parameters for function f:
tuple<Ps...> parameters;
};
// Partial template Specialization of gen_func for Functions with Return Type void:
template <class F , typename... Ps>
class gen_func<void,F,Ps...>
{
public:
// Constructor
gen_func(F&& f,Ps&&...parms){
func = forward<F>(f);
parameters=make_tuple(forward<Ps>(parms)...);
}
// execute-Function for public call:
template<typename... Vars>
void execute(Vars&&... vars) {
f_decon<Vars... , Ps...>( forward<Vars>(vars)... , parameters ); // Line 75
}
//
private:
// The wrapped Function f
F func;
// The tuple holding optional parameters for function f:
tuple<Ps...> parameters;
// "Deconvolution Function"
template<typename... Vars , typename... Ts >
void f_decon( Vars&&... vars , tuple<Ts...>& tup ){ // Line 85
f_proxy<Vars...,Ts...>( forward<Vars>(vars)... , tup , generic::sequence_generator<sizeof...(Ts)>{} );
}
// "Proxy-Function" calling the wrapped Function func:
template<typename... Vars , typename... Ts , size_t... Is>
void f_proxy( Vars&&... vars , tuple<Ts...>& tup , generic::index_sequence<Is...> ){
func( forward<Vars>(vars)... , get<Is>(tup)... );
}
};
void change(int& m,int n){
cout << "Changing!" << endl;
int res=42+n;
m=res;
}
int main()
{
typedef generic::generic_function_pointer<void,int&,int> chg_ptr;
gen_func<void,chg_ptr> y(change);
// The Variable to be altered by change
int j=0;
cout << "j='" << j << "'" << endl; // should be 0
// Wrapped Function call:
y.execute(j,21); // Line 113
cout << "j='" << j << "'" << endl; // should be 63
return 0;
}
编译器确实会抱怨:
X.cpp: In instantiation of ‘void gen_func<void, F, Ps ...>::execute(Vars&& ...) [with Vars = {int&, int}; F = void (*)(int&, int); Ps = {}]’:
X.cpp:113:15: required from here
X.cpp:75:12: error: no matching function for call to ‘gen_func<void, void (*)(int&, int)>::f_decon(int&, int, std::tuple<>&)’
X.cpp:75:12: note: candidate is:
X.cpp:85:14: note: template<class ... Vars, class ... Ts> void gen_func<void, F, Ps ...>::f_decon(Vars&& ..., std::tuple<_Args2 ...>&) [with Vars = {Vars ...}; Ts = {Ts ...}; F = void (*)(int&, int); Ps = {}]
X.cpp:85:14: note: template argument deduction/substitution failed:
X.cpp:75:12: note: mismatched types ‘std::tuple<_Elements ...>’ and ‘int’
代码通过引用传递变量x,以便通过包装函数更改对其进行更改,这似乎是错误的。我的程序方法完全错误吗?纠正起来简单吗?有没有更好的方法来实现我的目标?提前感谢您的建议 您可能想了解。我不太明白您为什么需要这种专门化。可能是一个g++错误?它是用clang++3.5uhhh编译的,这很难看。您可以通过推导所有模板参数来解决该问题。这可以通过改变成员函数f_decon和f_proxy的参数顺序来实现:重现g++的问题。叮当声很好用++