从指针到具有常量和非常量版本的成员函数的模板参数推导

Template argument deduction from pointer to member function with const and non-const versions

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

我有一个这样的代码:

#include <iostream>
template <typename T, typename FT>
void test( const FT & (T::*ptr)() const )
{
    std::cout << "const exists" << std::endl;
}
template <typename T, typename FT>
void test( FT & (T::*ptr)() )
{
    std::cout << "non-const exists" << std::endl;
}

struct A {
    const double & a() const { return a_; }
    double & a() { return a_; }
    private:
        double a_;
};
struct B {
    const double & b() const { return b_; }
    private:
        double b_;
};

int main( int argc, char **argv )
{
    test(&A::a);
    test(&B::b);
    return 0;
}

它没有编译错误消息:

prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:35: error: call of overloaded ‘test(<unresolved overloaded function type>)’ is ambiguous
prog.cpp:4: note: candidates are: void test(const FT& (T::*)()const) [with T = A, FT = double]
prog.cpp:10: note:                 void test(FT& (T::*)()) [with T = A, FT = double]

很清楚为什么编译器不知道该做什么。我的问题是,如果有非常量版本,如何调用具有non-const existsconst exists的版本?

注意:对于这个问题,我假设没有const版本,非const版本就不可能存在。然而,如果您有一个更通用的情况的解决方案,当您可以区分非常量存在但常量不存在的情况时,也将不胜感激。

所以简单的解决方案(ideone):

#include <iostream>
struct Tester {
    template <typename T, typename FT>
    void operator()( const FT & (T::*ptr)() const ) const
    {
        std::cout << "const exists" << std::endl;
    }
    template <typename T, typename FT>
    void operator()( FT & (T::*ptr)() )
    {
        std::cout << "non-const exists" << std::endl;
    }
};

struct A {
    const double & a() const { return a_; }
    double & a() { return a_; }
    private:
        double a_;
};
struct B {
    const double & b() const { return b_; }
    private:
        double b_;
};

int main( int argc, char **argv )
{
    Tester t;
    t(&A::a);
    t(&B::b);
    return 0;
}