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();
}