0

For e.g., rand() is a API for generating random numbers. Now i want to create my own rand() in the code. So the new rand() should overload the API already defined in library.

void getRandomValues () {
   int a = rand();
   ......
   ......
   int b = rand();
}

Above is a sample code.

Now i want to change above code to,

void getRandomValues () {
   auto a = rand();
   ......
   ......
   auto b = rand();
}

I want to write my own rand() function that will return not only integers, but some other custom values.

Is it possible to do that? Considering that rand is already part of standard C++ library.

Donn Dan
  • 3
  • 1
  • That would confuse everyone who looks at your code, and could possibly break uses of rand() that expect the normal behavior. If you want to assign random values to a member of class MyStuff, why not create an AddRandoms() member function for it? If you want a MultiTypeRand() with overloaded return types, use a new name like that instead but you might run into odd behavior with implicit casting like int to float. Passing the variable you want to set by reference like MyRand(int& i) and MyRand(float& f) might be best or using templates. – Dave S Jun 28 '21 at 20:26
  • 3
    [C++ cannot overload based only on return type](https://stackoverflow.com/questions/9568852/overloading-by-return-type), so no. Not possible. Option: Don't use or build upon `rand`. Odds are good that what you want is already in [``](https://en.cppreference.com/w/cpp/numeric/random). In general, [rand() Considered Harmful](https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful) – user4581301 Jun 28 '21 at 20:33

2 Answers2

0

The comments advise against doing this. But here's an actual answer on doing it.

If you want to call it with the same number and type of parameters, that's not "overloading". Your rand() (with no parameters) cannot overload std::rand() or ::rand() which also has no parameters.

You can have a function with the same name and signature defined in a different scope. You can arrange that your function is the one found in the current look-up context.

Use a using declaration to bring the desired function into the function's body block scope. So if you write,

void getRandomValues () 
{
   using mylib::rand;
   ...
   auto a = rand();  // finds mylib::rand, not ::rand etc.
   ......
   ......
JDługosz
  • 5,592
  • 3
  • 24
  • 45
  • 1
    This really is a bad idea for production code though. Maintenance will be a nightmare when someone else tries to work with this code a year later and misses the rand() redefinition. It might be OK if the using is skipped and `auto a = mylib::rand();` is used to make clear the overloading. – Dave S Jun 28 '21 at 21:16
  • @DaveS We know it's ill-advised, and as pointed out in the first sentence this provides a literal answer rather than further criticising it, as that was already done in the initial comments to the OP. – JDługosz Jun 29 '21 at 14:46
  • @PaulSanders [A namespace is one kind of scope](https://en.cppreference.com/w/cpp/language/scope#Namespace_scope). It's not an _or_ situation. – JDługosz Jun 29 '21 at 14:49
0

C++ doesn't support function overloading with multiple return types. So if you create a function int rand(), it will have to return an int unless you create other functions with different arguments.

Regarding the creation of random numbers, the STL has a library just for that. Take a look at the <random> header.

Regarding the redefinition of a rand() function, you can do it as long as you don't include the <stdlib.h> header file. The compiler and the linker will be smart enough to know which function you want to use. But this method prevents you from using the rand() function in the libc.

If you want to create a rand() function which can return any type, I think you have to use a template. Unfortunatly, the API will not be as simple as the one you gave.

template<typename type>
type rand()
{
    ...
}

struct C {};

int main()
{
    auto a = rand<int>();
    auto b = rand<double>();
    auto c = rand<C>();
}

This example compiles, so it should be fine for your needs. Although, I think redefining rand like this may not be a good idea.

Finally, if you are on Linux, you can dynamically change the functions called by an executable using the LD_PRELOAD environment variable. Which, I guess is another way to do what you said (but a very bad idea in my opinion).