考虑
struct Base
{
int foo(int);
int foo(int, int);
};
struct Child : Base
{
using Base::foo;
int foo(int, int, int);
};
理想情况下,我希望将仅Base
作为参数的foo
类int
作为参数引入Child
类,而不是将int
类作为参数using Base::foo;
1}}秒。有没有办法可以做到这一点?我的写作foo
带来了Base
的两种return gmdate($format, $date->getTimestamp());
方法。
答案 0 :(得分:27)
使用声明将使所有重载都可用。你无法防止这种情况发生。但事后可以delete
你不想要的超载:
struct Base
{
int foo(int);
int foo(int, int);
};
struct Child : Base
{
using Base::foo;
int foo(int, int) = delete;
int foo(int, int, int);
};
现在使用带有Child
的两个int重载是不正确的。然而,这不是一个完美的解决方案,因为客户端仍然可以调用Base版本:
Child c;
c.Base::foo(0, 0);
答案 1 :(得分:10)
无法将指定的重载函数引入派生类。名称查找规则处理名称,但重载的函数具有相同的名称foo
。
您可以在派生类中编写包装函数,例如
struct Child : Base
{
int foo(int x) { return Base::foo(x); }
int foo(int, int, int);
};
答案 2 :(得分:5)
我将列出其他答案中提供的两种解决方案,并详细说明它们之间的区别。
struct Child : Base
{
int foo(int x) { return Base::foo(x); }
int foo(int, int, int) { std::cout << 3; return 33; }
};
这完全符合您的要求,但您必须重复签名。
结果略有不同:
struct Child : Base
{
using Base::foo;
int foo(int,int)=delete;
int foo(int, int, int) { std::cout << 3; return 314; }
};
要想知道这有何不同,想象一下我们这样做了:
struct Grandkid : Child
{
using Child::foo;
int foo(double, double) { std::cout << 2; return 42; }
};
我们做了:
Grandkid x;
x.foo(3,4);
在使用=delete
的情况下,这会产生编译器错误。
3,4
更喜欢int,int
而不是double,double
。当我们=delete
int,int
重载时,仍然会考虑,选择它,然后我们选择=delete
d。当我们将其从重载分辨率中排除时,3,4
会选择double,double
。
手动转发排除 int,int
超载被考虑。 =delete
没有。
这与using Base::foo(int);
的虚构语法最相似(即,仅引入foo
的父重载之一)。
请注意,Grandkid
只是检测差异的一种简单方法。重要的是从重载决策中移除某些内容与=delete
重载之间存在差异。
Live example它的工作原理和where it doesn't。