代码之家  ›  专栏  ›  技术社区  ›  jcao219

C++调用模板函数函数无法调用重载方法

  •  2
  • jcao219  · 技术社区  · 14 年前

    template<class type, class ret, class atype1, class atype2, class atype3>
    ret call3(type *pClass, ret(type::* funcptr)(atype1, atype2, atype3), atype1 arg, atype2 arg2, atype3 arg3)
    {
        //do some stuff here
        return (pClass->*funcptr)(arg, arg2, arg3);
    }
    

    你这样做:

    class MyClass
    {
      public: 
        void test(int, int, int){};
        void test(int, int){};
        void test(int, int, const char *){};  //comment this line, and it works fine.
    };
    
    ...
    
        MyClass *a = new MyClass();
        call3(a, &MyClass::test, 1, 2, 3);
    

    g++会说:

    no matching function for call to `call3(MyClass*&, <unknown type>, int, int, int)'
    

    有什么办法解决这个问题吗? (我的代码可能也很糟糕,因为我不太擅长C++)。

    5 回复  |  直到 14 年前
        1
  •  3
  •   Michael Anderson    14 年前

    可以显式指定要使用的模板。

    call3<MyClass, void, int, int, int>( a, &MyClass::test, 1, 2, 3 );
    

    如果重新更改模板参数的顺序,则可以从参数中获得MyClass和void,因此需要重载时的调用将如下所示:

    call3<int,int,int>( a, &MyClass::test, 1, 2, 3 )
    

    注意,当您实际上不需要显式重载解析时,它仍然可以是

    call3( a, &MyClass::otherfunction, 1,2,3 );
    
        2
  •  3
  •   JoshD    14 年前

    您必须指定您需要的三个测试中的哪一个。这可以通过石膏完成:

    call3(a, static_cast<void (MyClass::*)(int, int, int)>(&MyClass::test), 1, 2, 3);
    

    不是很干净。最好给函数起不同的名字。

        3
  •  2
  •   Chubsdad    14 年前

    只有在通过查看每个参数/参数对明确确定模板参数时,参数推断才会成功。这意味着,在查看第二个参数/参数对时,它确实(而且不能)依赖于这样一个事实,即atype1、atype2和atype3都是“int”类型,即使您将模板参数重新排列为

    template<class type, class ret, class atype1, class atype2, class atype3> 
    ret call3(type *pClass, atype1 arg, atype2 arg2, atype3 arg3, ret(type::* funcptr)(atype1, atype2, atype3)) 
    { 
        //do some stuff here 
        return (pClass->*funcptr)(arg, arg2, arg3); 
    } 
    

    以下是支持这一点的标准引用:

    未推导的上下文是:

    这个 是使用限定的-id指定的。

    非类型模板参数或 引用模板参数。

    一个 函数参数的参数类型 在通话中使用 正在进行论点推导。

    哪个参数的函数参数 关联的函数参数是 函数或一组重载 功能(13.4),以及 以下适用:

    不止一个 函数与函数匹配 参数类型(导致 ,或

    匹配函数参数类型, 或

    参数包含一个或多个 函数模板。

    现在要解决这个问题,

    我认为唯一的解决方案是必须显式地指定模板参数,而不是依赖模板参数的推导。重新排列一下模板参数会有帮助

    template<class atype1, class atype2, class atype3, class type, class ret> 
    ret call3(type *pClass, ret(type::* funcptr)(atype1, atype2, atype3), atype1 arg, atype2 arg2, atype3 arg3) 
    { 
        //do some stuff here 
        return (pClass->*funcptr)(arg, arg2, arg3); 
    } 
    
    int main(){
        MyClass *a = new MyClass(); 
        call3<int, int, int>(a, &MyClass::test, 1, 2, 3); 
    }
    
        4
  •  0
  •   Alex Emelianov    14 年前

    编译器无法推断返回参数类型。必须指定 call3

        5
  •  0
  •   Yogesh Arora    14 年前

    我认为这里的问题是编译器无法解决 test 你所指的功能。

    void test(int, int, int);
    void test(int, int, const char *); 
    

    现在如果你打电话 测试

    test(1, 2, 3);
    

    3 可以隐式转换为 const char * . 所以编译器无法在函数的两个重载之间进行解析 测试

    乔希的解决方案应该能解决你的问题