请考虑以下代码:
#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()。
发布于 2015-08-05 20:19:57
bar(std::forward<Args>(args)...)成形性的研究。
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的声明之后。
演示。
发布于 2015-08-05 20:42:23
感谢nwp的提示(虽然我不确定这是否是他的意思)和T.C.的调试提示,我有这个替代解决方案。但是T.C.的解决方案要好得多。
#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).
}https://stackoverflow.com/questions/31840475
复制相似问题