Could not deduce template argument & pointer to member

十年热恋 提交于 2019-12-22 00:25:24

问题


I am encountering the C2783 error with Visual C++ (could not deduce template argument), I have the following test case:

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

When commenting the line

static inline void add(ObjectType* obj, typename SPKSetterPattern<TypeCode,ObjectType,U>::func attrSetter) {}

and uncommenting the line following, the code compiles.

I don't understand why, because for me the second argument of 'helper::add' is still the same...

Thanks for help.


回答1:


You're asking the compiler to do a reverse lookup: to find all specializations on U of SPKSetterPattern and all their definitions of func, find the one definition that matches your actual argument, and then deduce the template arguments as those used for that specialization.

It doesn't work like that.

You don't get reverse lookup for template matching.


EDIT: due to requests in comment:

The following code deduces the argument type for a method with all arguments of the same type, and known result type void and class 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; };

The original code can then be amended as follows:

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

However, with access to some C++11 support probably std::function is a better alternative?



来源:https://stackoverflow.com/questions/9649904/could-not-deduce-template-argument-pointer-to-member

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!