问题 c ++标准中的重载vs默认参数


我正在读另一个问题,它让我思考。标准通常指定在其描述中具有默认参数的函数。标准是否允许将这些作为重载写入?

例如,标准说明了这一点 std::basic_string::copy 有以下声明:

size_type copy(Ch* p, size_type n, size_type pos = 0) const;

标准库的符合实现是否可以实现这两个函数?

size_type copy(Ch* p, size_type n, size_type pos) const;
size_type copy(Ch* p, size_type n) const;

在此示例中,第二个版本可以跳过 if(pos > size()) { throw out_of_range(); } 第一个必要的测试。微观优化,但你仍然看到了例子的重点。


11490
2018-02-17 16:44


起源

在默认参数的情况下,编译器(理论上)是否能够进行相同的优化? - Harper Shelby
@Harper Shelby,也许,也许不是。这只是一个例子。我的问题实际上是关于标准库的编写者是否允许这样做。 - Evan Teran
@HarperShelby:仅在内联函数调用时。 - Fred Nurk
@Evan Teran:我认为这是一个很好的问题。我的直觉是“不,标准规定了声明,所以你必须这样做”,但几年前我在comp.lang.c ++上的短暂停留让我觉得我真的很少知道标准。显然,可能存在更复杂的场景,程序员可能会进行某种改进,编译器难以确定。 - Harper Shelby
@Matthieu M。:我认为它不会产生 更差 码。我知道至少gcc实现了部分函数内联来解决代码重复问题。我怀疑其他编译器有类似的聪明优化。 - Evan Teran


答案:


标准库的符合实现是否可以实现这两个函数?

是。 C ++标准(C ++ 03 17.4.4.4/2-3)说:

实现可以在[Standard Library]类中声明其他非虚拟成员函数签名:

- 通过向成员函数签名添加带默认值的参数;但是,相同的纬度不会扩展到虚拟或全局或非成员函数的实现。

- 通过两个或多个具有等效行为的成员函数签名用默认值替换成员函数签名;

- 通过为成员函数名称添加成员函数签名。

对C ++标准库中描述的成员函数签名的调用与实现声明没有其他成员函数签名的行为相同


15
2018-02-17 16:55



+1。我收回下面的答案:) - icabod
我认为这仅适用于STL,而不适用于用户定义的代码。它可能会破坏与此类似的代码: struct base { virtual void foo( int i = 0 ); }; struct derived : base { void foo(); }; struct rederived : derived { void foo(); }; 通过将默认值实现为两个不同的函数,两者都必须标记为虚拟,并在调用时 foo() 在类型的对象上 rederived 通过参考 derived 它会调用最终的覆盖(rederived::foo()而不是预期的 derived::foo()。 - David Rodríguez - dribeas
@David:是的,它只适用于标准库成员函数(这是引用的Standardese的第一句话)。我认为问题完全是关于C ++标准库类和成员函数;我可能误解了它。 - James McNellis
:)好像我是一个没有正确阅读问题的人。 - David Rodríguez - dribeas