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 错误:显式专门化';foo';类内范围_Templates_C++11_Nested_Traits - Fatal编程技术网

Templates 错误:显式专门化';foo';类内范围

Templates 错误:显式专门化';foo';类内范围,templates,c++11,nested,traits,Templates,C++11,Nested,Traits,通过使用模板特性,我很难抽象出三个类似的函数 这是我的代码: extern "C" PyObject* M_method_noargs_call_handler ( PyObject* _self_and_name_tuple, PyObject* ); extern "C" PyObject* M_method_varargs_call_handler( PyObject* _self_and_name_tuple, PyObject* _args ); extern "C" PyObjec

通过使用模板特性,我很难抽象出三个类似的函数

这是我的代码:

extern "C" PyObject* M_method_noargs_call_handler ( PyObject* _self_and_name_tuple, PyObject*  );
extern "C" PyObject* M_method_varargs_call_handler( PyObject* _self_and_name_tuple, PyObject* _args );
extern "C" PyObject* M_method_keyword_call_handler( PyObject* _self_and_name_tuple, PyObject* _args, PyObject* _keywords );

template<TEMPLATE_TYPENAME T>
class ExtModule : public ExtModuleBase
{
public:
    ExtModule( const char* name ) : ExtModuleBase( name ) { }
    virtual ~ExtModule() { }

protected:

    typedef std::map< std::string, MethodDefExt<T>* > method_map_t;

    using F0 = typename MethodDefExt<T>::F0;
    using F1 = typename MethodDefExt<T>::F1;
    using F2 = typename MethodDefExt<T>::F2;

    static constexpr auto& h0 = M_method_noargs_call_handler;
    static constexpr auto& h1 = M_method_varargs_call_handler;
    static constexpr auto& h2 = M_method_keyword_call_handler;

    static void add_noargs_method ( const char* name, F0 f ) { 
        methods()[ std::string(name) ] = new MethodDefExt<T>( name, f, h0 ); }

    static void add_varargs_method( const char* name, F1 f ) { 
        methods()[ std::string(name) ] = new MethodDefExt<T>( name, f, h1 ); }

    static void add_keyword_method( const char* name, F2 f ) { 
        methods()[ std::string(name) ] = new MethodDefExt<T>( name, f, h2 ); }
    :
}
现在,F0 F1 F2自身依赖于T,因此不幸的是,我不能将这些特征排除在类定义之外(我不认为…?)

我知道这可能是荒谬的过度结构,但有没有办法做到这一点

PS这里是MethodDefExt:

template<class T>
class MethodDefExt //: public PyMethodDef
{
public:
    typedef Object (T::*F0)( );
    typedef Object (T::*F1)( const Tuple& args );
    typedef Object (T::*F2)( const Tuple& args, const Dict& kws );

    // NOARGS
    MethodDefExt (
        const char* _name,
        F0 _function,
        H0 _handler
    )
    {
        meth_def.ml_name = const_cast<char *>( _name );
        meth_def.ml_meth = reinterpret_cast<PyCFunction>( _handler );
        meth_def.ml_flags = METH_NOARGS;
        f0 = _function;
    }

    // VARARGS
    MethodDefExt (
        const char* _name,
        F1 _function,
        H1 _handler
    )
    {
        meth_def.ml_name = const_cast<char *>( _name );
        meth_def.ml_meth = reinterpret_cast<PyCFunction>( _handler );
        meth_def.ml_flags = METH_VARARGS;
        f1 = _function;
    }

    // VARARGS + KEYWORD
    MethodDefExt (
        const char* _name,
        F2 _function,
        H2 _handler
    )
    {
        meth_def.ml_name = const_cast<char *>( _name );
        meth_def.ml_meth = reinterpret_cast<PyCFunction>( _handler );
        meth_def.ml_flags = METH_VARARGS | METH_KEYWORDS;
        f2 = _function;
    }

    ~MethodDefExt() { }

    PyMethodDef meth_def;

    F0 f0 = nullptr;
    F1 f1 = nullptr;
    F2 f2 = nullptr;

    Object py_method;
};
模板
类methoddeext/:public PyMethodDef
{
公众:
typedef对象(T::*F0)();
typedef对象(T::*F1)(常量元组和参数);
typedef对象(T::*F2)(常量元组和参数、常量Dict和kws);
//诺尔斯
方法文本(
常量字符*\u名称,
F0_函数,
H0_处理器
)
{
meth_def.ml_name=const_cast(_name);
meth_def.ml_meth=reinterpret_cast(_handler);
meth_def.ml_flags=meth_NOARGS;
f0=_函数;
}
//瓦拉格斯
方法文本(
常量字符*\u名称,
F1_函数,
H1\u处理器
)
{
meth_def.ml_name=const_cast(_name);
meth_def.ml_meth=reinterpret_cast(_handler);
meth_def.ml_flags=meth_VARARGS;
f1=_函数;
}
//VARARGS+关键字
方法文本(
常量字符*\u名称,
F2 _函数,
H2_处理器
)
{
meth_def.ml_name=const_cast(_name);
meth_def.ml_meth=reinterpret_cast(_handler);
meth_def.ml_flags=meth_VARARGS | meth_关键字;
f2=_函数;
}
~MethodDefExt(){}
PyMethodDef meth_def;
F0 F0=nullptr;
F1=空PTR;
F2=空PTR;
对象py_方法;
};

}//名称空间Py

说您首选的策略是将h_trait移到类之外。你面临的问题是,你目前正在完全专门化h_特质的依赖类型(即F0和F1依赖于T)。由于您希望类型具有灵活性,您可能会考虑以“非依赖”的方式进行专门化,例如:

template <typename T>
struct h_trait;

template <typename T>
struct h_trait<typename MethodDefExt<T>::F0> {...} // can't specialize this way!
但是我们必须专门研究可能使用的每种类型

因此,让我们混合方法并部分专门化h_trait:我们将推导一个模板参数,并根据推导出的参数指定另一个模板参数:

#include <iostream>

void h0(int) { std::cout << "h0\n"; }
void h1(int,char) { std::cout << "h1\n"; }

template <typename T> 
struct MethodDefExt { 
    typedef void(T::*F0)(int); 
    typedef void(T::*F1)(int,char); 
}; 

template <typename, typename> 
struct h_trait; 

template <typename T> 
struct h_trait<T, typename MethodDefExt<T>::F0> 
{ 
    static constexpr auto& h = h0;
}; 

template <typename T> 
struct h_trait<T, typename MethodDefExt<T>::F1> 
{ 
    static constexpr auto& h = h1;
}; 

template <typename T> 
struct YourClass { 
    using F0 = typename MethodDefExt<T>::F0;
    using F1 = typename MethodDefExt<T>::F1;

    template <typename F>
    void do_internal(F f)
    {
        h_trait<T,F> b; 
        b.h(1); // calls our awkwardly bound function just 
                // to demonstrate
    }   

    void foo() { 
        F0 f{};
        do_internal(f); // doit(F0{}); // ICE IN gcc 4.8.1
    }
};

struct A {}; 

int main() {
    YourClass<A> b; // doesn't work with non-class type parameter
    b.foo();
}
#包括

无效h0(内部){std::我是否可以删除我之前的评论,因为我误解了你的问题。希望我现在能理解:它是否有效地与相同?如果是,答案对你有用吗?如果不是,你能更新你的问题,以更清楚地显示它不起作用的方式吗?为什么你不能保留你现在拥有的三个单独的功能,但是给它们取一个相同的名字,
add_method
?你确实想要“三个重载”,不是吗?
template <typename T>
struct h_trait;

template <typename T>
struct h_trait<typename MethodDefExt<T>::F0> {...} // can't specialize this way!
template <>
struct h_trait<MethodDefExt<SPECIFIC_TYPE>::F0> { ... }
#include <iostream>

void h0(int) { std::cout << "h0\n"; }
void h1(int,char) { std::cout << "h1\n"; }

template <typename T> 
struct MethodDefExt { 
    typedef void(T::*F0)(int); 
    typedef void(T::*F1)(int,char); 
}; 

template <typename, typename> 
struct h_trait; 

template <typename T> 
struct h_trait<T, typename MethodDefExt<T>::F0> 
{ 
    static constexpr auto& h = h0;
}; 

template <typename T> 
struct h_trait<T, typename MethodDefExt<T>::F1> 
{ 
    static constexpr auto& h = h1;
}; 

template <typename T> 
struct YourClass { 
    using F0 = typename MethodDefExt<T>::F0;
    using F1 = typename MethodDefExt<T>::F1;

    template <typename F>
    void do_internal(F f)
    {
        h_trait<T,F> b; 
        b.h(1); // calls our awkwardly bound function just 
                // to demonstrate
    }   

    void foo() { 
        F0 f{};
        do_internal(f); // doit(F0{}); // ICE IN gcc 4.8.1
    }
};

struct A {}; 

int main() {
    YourClass<A> b; // doesn't work with non-class type parameter
    b.foo();
}