首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >过载技巧

过载技巧
EN

Stack Overflow用户
提问于 2015-08-05 18:47:46
回答 2查看 93关注 0票数 0

请考虑以下代码:

代码语言:javascript
复制
#include <iostream>

class A {
public:
    template <typename... Args> void execute(Args&&... args) {foo(std::forward<Args>(args)...);}
    template <typename... Args> void doIt(Args&&... args) {bar(std::forward<Args>(args)...);}
private:
    void foo() {}
    void foo(int) {}
    void foo(int, char) {}
    void foo(bool, int, double) {}
    void bar() {foo();}  // *** Added
    void bar(int) {}
    void bar(int num, char c) {foo(num, c);}  // *** Added
    void bar(bool, int, double) {}
};

int main() {
    A a;
    a.doIt();
    a.doIt(5,'t');
}

A::doIt将使用与A::execute相同的重载类型,并将使用bar的重载来处理其中一些重载(对于这些重载,bar的重载是唯一的),而对其他重载则使用foo的重载。为了完成这一任务,我简单地添加了void bar() {foo();}void bar(int num, char c) {foo(num, c);}。这并不痛苦,但假设有很多这样的转发要做。当需要新的doIt重载时,想想维护问题,以及为它们定义的新foo重载(很容易忘记转发的东西)。

是否有一种方法可以删除这些额外的bar重载(这只是转发到foo),而不是修改当前定义的doIt(Args&&... args)函数,以便在不存在这样的条形重载的情况下,它将调用foo的重载?换句话说,删除我添加的两个bar重载,并且仍然按照doIt的新定义编译main()。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-05 20:19:57

bar(std::forward<Args>(args)...)成形性的研究。

代码语言:javascript
复制
class A {
private:
    void foo();
    void foo(int);
    void foo(int, char);
    void foo(bool, int, double);
    void bar(int);
    void bar(bool, int, double);

    template <typename... Args> 
    auto doIt_impl(int, Args&&... args) -> decltype(bar(std::forward<Args>(args)...)){
        bar(std::forward<Args>(args)...);
    }
    template <typename... Args> 
    auto doIt_impl(long, Args&&... args) -> void {
        foo(std::forward<Args>(args)...);
    }

public:
    template <typename... Args> void doIt(Args&&... args) {
        doIt_impl(0, std::forward<Args>(args)...);
    }
};

虚拟的第一个参数确保bar-calling重载doIt_impl是首选的,如果可行的话。另外,需要注意的是,尾随返回类型不会得到类范围查找,因此doIt_impl的声明必须在bar的声明之后。

演示

票数 4
EN

Stack Overflow用户

发布于 2015-08-05 20:42:23

感谢nwp的提示(虽然我不确定这是否是他的意思)和T.C.的调试提示,我有这个替代解决方案。但是T.C.的解决方案要好得多。

代码语言:javascript
复制
#include <iostream>

class A_Foo {
protected:
    virtual void foo() {std::cout << "foo().\n";}
    virtual void foo(int) {std::cout << "foo(int).\n";}
    virtual void foo(int, char) {std::cout << "foo(int, char).\n";}
    virtual void foo(bool, int, double) {std::cout << "foo(bool, int, double).\n";}
};

class A_Bar : private A_Foo {
public:
    using A_Foo::foo;  // This is needed.  Else all the declarations of foo in A_Foo are hidden.
    virtual void foo(int) override {std::cout << "bar(int).\n";}
    virtual void foo(bool, int, double) override {std::cout << "bar(bool, int, double).\n";}
};

class A : private A_Bar {
public:
    template <typename... Args> void execute(Args&&... args) {
        A_Foo::foo(std::forward<Args>(args)...);
    }
    template <typename... Args> void doIt(Args&&... args) {
        A_Bar::foo(std::forward<Args>(args)...);
    }
};

int main() {
    A a;
    a.doIt();  // foo().
    a.doIt(5);  // bar(int).
    a.doIt(5,'t');  // foo(int, char).
    a.doIt(true,5,1.8);  // bar(bool, int, double).
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31840475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档