【问题标题】:C++11/templates: Select the correct overloading of a functionC++11/模板:选择正确的函数重载
【发布时间】:2013-03-22 04:36:24
【问题描述】:

关于this question,这可能过于简单化了,我在这里举一个更复杂的例子。我假装的问题用以下代码描述:

// test3.cpp

using namespace std;

template<typename T>
struct exer
{
    template<typename R, typename... rArgs, typename... pArgs>
    R operator()(R(T::*f)(rArgs...), pArgs&&... args)
    {
       return (t.*f)(forward<pArgs>(args)...);
    }

    T t;
};

struct A
{
    int addition() { return 0; }

    template<typename... Args>
    int addition(int a, Args... args) { return a + addition(args...); }
};

struct B
{
public:
    template<typename... Args>
    int addition(Args&&... args)
    {
       return m_e(&A::addition, forward<Args>(args)...);
    }

private:
    exer<A> m_e;
};

int main()
{
    B b;

    cout << b.addition(1, 2, 3, 4) << endl;
}

这里的问题是,在B::addition 的实例化中,&amp;A::addition 的类型是未知的,因为存在不同的重载。此外,B::addition 也不知道必须使用哪个重载。在调用函数之前,它不知道编译器。但是,为了正确指定必须在 exer&lt;A&gt;::operator() 中使用的重载,我需要对 &amp;A::addition 进行强制转换以将其强制转换为正确的重载。

如何提取目标函数正确重载的类型?

【问题讨论】:

    标签: c++ templates c++11 word-wrap overloading


    【解决方案1】:

    换个问题。如果您可以让exer 采用可调用对象而不是指向成员函数的指针,如下所示:

    template<typename T>
    struct exer
    {
        T t;
        template<typename F, typename... pArgs>
        auto operator()(F f, pArgs&&... args)
        -> decltype(f(t, forward<pArgs>(args)...))
        {
           return f(t, forward<pArgs>(args)...);
        }
    
    };
    

    那么你可以这样做:

    struct B
    {
    public:
        template<typename... Args>
        int addition(Args&&... args)
        {
            struct Invoker {
                auto operator()(A& a, Args&&... args) const
                    ->decltype(a.addition(std::forward<Args>(args)...))
                { return a.addition(std::forward<Args>(args)...); }
            };
            return m_e(Invoker(), forward<Args>(args)...);
        }
    
    private:
        exer<A> m_e;
    };
    

    现在选择正确的A::addition 是由编译器使用正常的重载解析规则完成的。

    您可以使用 lambda 表达式代替 Invoker,这可以减少一些重复:

            return m_e( [](A& a, Args&&... as) {
                          return a.addition(forward<Args>(as)...);
                        },
                        forward<Args>(args)...);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-10
      • 1970-01-01
      • 1970-01-01
      • 2010-11-22
      • 2020-09-02
      • 1970-01-01
      相关资源
      最近更新 更多