无法推断模板参数和指向成员的指针
Could not deduce template argument & pointer to member
我在Visual C++中遇到C2783错误(无法推导模板参数),我有以下测试用例:
enum SPKType { A, B, C, D };
template<SPKType TypeCode, class ObjectType, typename U>
struct SPKSetterPattern
{
typedef void (ObjectType::* func)(U);
};
template<class ObjectType, typename U>
struct SPKSetterPattern<B,ObjectType,U> { typedef void (ObjectType::* func)(U,U); };
template<class ObjectType, typename U>
struct SPKSetterPattern<C,ObjectType,U> { typedef void (ObjectType::* func)(U,U,U); };
template<class ObjectType, typename U>
struct SPKSetterPattern<D,ObjectType,U> { typedef void (ObjectType::* func)(U,U,U,U); };
template<typename ObjectType, SPKType TypeCode>
struct helper
{
template<typename U>
static inline void add(ObjectType* obj, typename SPKSetterPattern<TypeCode,ObjectType,U>::func attrSetter) {}
//static inline void add(ObjectType* obj, void (ObjectType::*attrSetter)(U)) {}
};
class test
{
public:
template<typename ObjType>
void init()
{
// Supposed to work
helper<ObjType,A>::add(this, &test::setA);
//helper<ObjType,B>::add(this, &test::setB);
//helper<ObjType,C>::add(this, &test::setC);
//helper<ObjType,D>::add(this, &test::setD);
helper<ObjType,A>::add(this, &test::setAf);
// Supposed to fail
//helper<ObjType,B>::add(this, &test::setBf);
}
test() { init<test>(); }
void setA(int a) {}
void setB(float,float) {}
void setC(int,int,int) {}
void setD(int,int,int,int) {}
void setAf(double a) {}
void setBf(int,double) {}
};
int main()
{
test t;
return 0;
}
评论行时
static inline void add(ObjectType* obj, typename SPKSetterPattern<TypeCode,ObjectType,U>::func attrSetter) {}
并取消对下面一行的注释,代码将编译。
我不明白为什么,因为对我来说,"helper::add"的第二个参数仍然是一样的。。。
谢谢你的帮助。
您要求编译器执行反向查找:要查找SPKSetterPattern
的U
上的所有专门化及其对func
的所有定义,请找到与实际参数匹配的一个定义,然后将模板参数推断为用于该专门化的参数。
它不是那样工作的。
模板匹配无法进行反向查找。
编辑:由于评论中的请求:
以下代码为具有相同类型的所有参数、已知结果类型void
和类Class
:的方法推导参数类型
template< class Class, class MethodPtr >
struct ArgType;
template< class Class, class Arg >
struct ArgType< Class, void (Class::*)( Arg ) >
{ typedef Arg T; };
template< class Class, class Arg >
struct ArgType< Class, void (Class::*)( Arg, Arg ) >
{ typedef Arg T; };
template< class Class, class Arg >
struct ArgType< Class, void (Class::*)( Arg, Arg, Arg ) >
{ typedef Arg T; };
template< class Class, class Arg >
struct ArgType< Class, void (Class::*)( Arg, Arg, Arg, Arg ) >
{ typedef Arg T; };
原始代码可以修改如下:
template<typename ObjectType, SPKType TypeCode>
struct helper
{
template< typename U >
static void ungoodAdd(
ObjectType* obj,
typename SPKSetterPattern<TypeCode,ObjectType,U>::func attrSetter
)
{
(void)obj; (void)attrSetter;
}
template< typename MethodPtr >
static void add(
ObjectType* pObject,
MethodPtr method
)
{
typedef typename ArgType< ObjectType, MethodPtr >::T Arg;
ungoodAdd<Arg>( pObject, method );
}
// template<typename U>
// static inline void add(ObjectType* obj, typename SPKSetterPattern<TypeCode,ObjectType,U>::func attrSetter) {}
//static inline void add(ObjectType* obj, void (ObjectType::*attrSetter)(U)) {}
};
然而,有了一些C++11支持,std::function
可能是更好的选择吗?
相关文章:
- 从成员指针到整个结构/类的强制转换
- OOP 中的单成员指针
- 使用结构成员指针在C++中填充结构
- 聚合初始化,将成员指针设置为同一结构成员
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 共享 C++ 的数据成员指针
- 如何声明指向成员内容的成员指针m_pmd/m_pmf并访问它们?
- 从类C++外部调用指向成员方法的成员指针
- 结构成员指针是否自动初始化为零?
- 如何删除类内类类型的类成员指针
- 是否打印指向已定义 int 的成员指针
- 指向常量的成员指针
- 通过此指针访问时的成员差异和自身的成员指针(简单的 QT 示例问题)
- 类数据成员指针的非类型模板参数包无法使用 gcc 编译
- 为什么我不能在同一行中定义两个相同类型的类的成员指针
- 将类成员指针传递给 Lambda 捕获列表 c++11
- 在单一实例类中将成员指针设置为 null 的正确方法是什么
- 无法删除在destructor中的成员指针的课程
- 删除对象而不调用成员指针的析构函数
- 当派生类的基类具有成员指针时,对其进行深层复制