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
Templates 如何编写同时包含变量和参数的泛型函子类?_Templates_Generics_C++11_Tuples_Variadic - Fatal编程技术网

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++的问题。叮当声很好用++