我想覆盖一个std函数的行为,比如说std :: time。是否可以调用std :: time并将其路由到我的自定义函数中?
我想覆盖一个std函数的行为,比如说std :: time。是否可以调用std :: time并将其路由到我的自定义函数中?
std
命名空间通常是受限制的,不允许添加新函数、重载、类或其他任何东西到 std
命名空间中,这属于 **未定义行为**。
唯一的例外是模板特化。 您可以提供在std
命名空间中的函数特化。 一个经常进行此操作的函数是 std::swap
。
true
或false
。更好的方法是编写自己的包装函数,比如说tim_time()
,它可以在内部调用std::time()
,也可以不调用。不要称之为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 函数。
不具有可移植性。在理解标准未定义发生什么的前提下,您通常可以在命名空间std中定义任何符号和函数,或链接到定义这些符号的库,或者其他操作。这只是未定义的行为。因此,您所能做的就是尝试并希望它不会在编译器的下一个版本中出现问题。
话虽如此,对于大多数编译器而言,它可能会基本正常工作,只要避免与“真正”的std::time发生一次定义规则冲突即可。这是因为大多数编译器实际上并没有对命名空间std进行任何特殊处理,它们用于实现它的头文件和库与您自己编写的头文件和库没有什么不同。
然而,Dima绝对是正确的,这样做几乎总是一个非常糟糕的想法。也许如果您被困在某个调试地狱中,基本上想要向std::time添加日志记录但无法实现,那么值得考虑。否则不要这样做。如果您想测试一些代码,以查看它是否在各种时间下正确工作,则将该代码传递给一个参数(或模板参数),指定应调用哪个时间函数。
extern "C" time_t time(time_t *value)
{
...
}
如果你很幸运,链接器会将你的版本的std::time
与标准库中的版本绑定得更紧密。当然,这并不保证会起作用,或者以你想要的方式链接。而且,缺点是你再也无法访问原始的std::time
了。
正如其他人发布的那样,这种行为并不可移植。我相信它在Linux上可以工作。我也相当确定它在Windows上不起作用(链接器会抱怨冲突)。