我想覆盖std函数的行为,比如说std :: time。是否可以调用std :: time并通过我的自定义函数进行路由?
答案 0 :(得分:11)
一般来说,std
命名空间是不受限制的。向std
命名空间添加新函数,重载,类或任何其他内容是**未定义的行为*。
仅例外是模板特化。您可以在std
命名空间中提供函数的特化。经常这样做的函数是std::swap
。
答案 1 :(得分:5)
这听起来像个坏主意。有点像重新定义true
或false
。更好的方法是编写自己的包装函数,比如tim_time()
,它可能会或可能不会在内部调用std::time()
。
答案 2 :(得分:2)
不是调用它std::time
,而是路由您有时可能通过不同命名空间覆盖的所有调用。
namespace mystd{
using namespace std;
void time() { ... }
}
// ...
mystd::time(); // not std::time
mystd::copy(...); // calls std::copy, unless you override it like time()
然后对mystd::time
的调用将调用该函数的修改版本。如果调用非重写函数,例如mystd::copy
,它将被正确解析为原始的std函数。
答案 3 :(得分:1)
不便携。根据标准没有定义发生了什么的理解,您通常可以在命名空间std中定义您喜欢的任何符号和函数,或者链接到定义这些符号的库,或者其他任何符号。这只是未定义的行为。所以你所能做的就是吮吸它并看到它,并希望它不会在你的编译器的下一个版本中破坏。
也就是说,对于大多数编译器来说,如果你避免与“真正的”std :: time发生单一定义规则冲突,它可能大部分都可以工作。这是因为大多数编译器实际上并没有对命名空间std做任何特殊操作,并且他们用来实现它的头文件和库与你自己编写的头文件和库没有任何不同。
但是,迪马绝对是正确的,这样做不合标准几乎总是一个非常糟糕的主意。也许如果你陷入一些调试地狱,你基本上想要将记录添加到std :: time,但不能,那么值得思考。否则不要去那里。如果你想测试一些代码,看它是否在不同时间正常工作,那么传递一个参数(或模板参数)来指定它应该调用哪个时间函数。答案 4 :(得分:1)
在某些平台上,您可以将其关闭。在源代码中,定义函数,即
extern "C" time_t time(time_t *value)
{
...
}
如果您很幸运,链接器将比标准库中的版本更紧密地绑定您的std::time
版本。当然,不能保证这会起作用,或者按照你想要的方式联系起来。作为缺点,您将无法再访问原始std::time
。
正如其他人发布的那样,这不是可移植行为。我很确定它适用于Linux。我也很确定它在Windows上不起作用(链接器抱怨冲突)。