重写 std 函数

发布于 2024-08-03 08:09:14 字数 66 浏览 6 评论 0原文

我想重写 std 函数的行为,例如 std::time。是否可以调用 std::time 并通过我的自定义函数路由它?

I'd like to override the behavior of an std function, say std::time. Is it possible to call std::time and have it routed through my custom function?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

趁微风不噪 2024-08-10 08:09:14

一般来说,std 命名空间是禁止使用的。向 std 命名空间添加新函数、重载、类或其他任何内容都是**未定义行为*。

唯一的例外是模板特化。您可以在 std 命名空间中提供函数的特化。经常执行此操作的函数是 std::swap。

The std namespace is off limits, generally speaking. Adding new functions, overloads, classes or anything else to the std namespace is **undefined behavior*.

The only exception is template specializations. You may provide specializations of functions in the std namespace. A function where this is often done is std::swap.

默嘫て 2024-08-10 08:09:14

这听起来是一个非常糟糕的主意。有点像重新定义 truefalse。更好的方法是编写自己的包装函数,例如 tim_time(),它可能会也可能不会在内部调用 std::time()

This sounds like a very bad idea. Kind of like redefining true or false. A better way would be to write your own wrapper function, say tim_time(), which may or may not call std::time() internally.

三五鸿雁 2024-08-10 08:09:14

不要将其称为 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 函数。

Instead of calling it std::time, route all calls that you might sometimes override through a different namespace.

namespace mystd{
    using namespace std;
    void time() { ... }
}

// ...
mystd::time();  // not std::time
mystd::copy(...); // calls std::copy, unless you override it like time()

Then the call to mystd::time will call the modified version of the function. If you call non-overridden function, for example, mystd::copy, it will be correctly resolved to the original std function.

执笏见 2024-08-10 08:09:14

不便于携带。基于标准没有定义发生的情况的理解,您通常可以在命名空间 std 中定义您喜欢的任何符号和函数,或者链接到定义这些符号的库,或者其他什么。这只是未定义的行为。所以你所能做的就是把它吸进去看看,并希望它不会在你的编译器的下一个版本中崩溃。

也就是说,对于大多数编译器来说,只要您避免与“真实”std::time 发生单一定义规则冲突,它可能大部分都能工作。这是因为大多数编译器实际上并没有对命名空间 std 做任何特殊的事情,并且它们用于实现它的头文件和库与您自己编写的头文件和库没有任何不同。

不过,迪马是绝对正确的,像这样不符合标准几乎总是一个非常糟糕的主意。也许如果您陷入了一些调试地狱,您基本上想向 std::time 添加日志记录,但不能,那么值得考虑。否则不要去那里。如果您想测试某些代码,看看它在不同时间是否正常工作,然后向该代码传递一个参数(或模板参数),指定它应该调用哪个时间函数。

Not portably. On the understanding that the standard doesn't define what happens, you can usually define whatever symbols and functions you like in namespace std, or link against a library that defines those symbols, or whatever. It's just undefined behaviour. So all you can do is suck it and see, and hope it doesn't break in the next release of your compiler.

That said, with most compilers it will probably mostly work, provided that you avoid a one-definition-rule clash with the "real" std::time. This is because most compilers don't actually do anything special with namespace std, and the header files and libraries they use to implement it are not really any different from header files and libraries you could write yourself.

Dima is absolutely right, though, that going off-standard like this is a almost always a very bad idea. Maybe if you're stuck in some debugging hell where you basically want to add logging to std::time, but can't, then it's worth thinking about. Otherwise don't go there. If you want to test some code, to see whether it works correctly at various times, then pass that code a parameter (or template parameter) specifying which time function it should call.

糖粟与秋泊 2024-08-10 08:09:14

在某些平台上,您可以实现这一点。在源代码中,定义函数,即

extern "C" time_t time(time_t *value)
{
        ...
}

如果幸运的话,链接器将比标准库中的版本更紧密地绑定您的 std::time 版本。当然,不能保证这会起作用,或者以您想要的方式链接。缺点是,您不再能够访问原始的 std::time 。

正如其他人所发布的,这不是可移植的行为。我很确定它可以在 Linux 上运行。我也相当确定它在 Windows 上不起作用(链接器抱怨冲突)。

On some platforms, you can pull this off. In your source code, define the function, i.e.

extern "C" time_t time(time_t *value)
{
        ...
}

If you're lucky, the linker will bind your version of std::time more tightly than the one from the standard library. Of course, there's no guarantee that this will work, or be linked the way you want. And as a downside, you no longer have any access to the original std::time.

As everyone else has posted, this isn't portable behavior. I'm pretty sure it works on Linux. I'm also fairly certain it doesn't work on Windows (linker complains about the conflict).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文