无法推断模板参数和指向成员的指针

Could not deduce template argument & pointer to member

本文关键字:成员 指针 参数      更新时间:2023-10-16

我在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"的第二个参数仍然是一样的。。。

谢谢你的帮助。

您要求编译器执行反向查找:要查找SPKSetterPatternU上的所有专门化及其对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可能是更好的选择吗?