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?
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.
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.
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.
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
.
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).