Ben
Ben

Reputation: 69

Redefining C++ function using a struct

Let's say, I have the following in a "foo.hpp". I have a function with the same name as the struct.

int foo(int i);

struct foo{
 foo(int i){ value = i;}
 operator int() {return value;}
 int value;
};

If I call it in main like so:

int main()
{
 std::cout << foo(1) << std::endl; // function is called, not the struct, why??
}

Why does the compiler always link the function and not the struct? If possible, how to change that the struct is linked, not the function?

Ultimately, I would like to overwrite a function in a library by adding an extra header file and overwriting the function with the struct. That way, I am hoping to change one specific function, but continue using all other library functions and not alter the library code at the same time.

Upvotes: 3

Views: 508

Answers (2)

CHKingsley
CHKingsley

Reputation: 329

There is a lot going on here.

When you have a function inside a struct that has the same name as the struct, that is a "constructor". It is called to fill in the member variables of the struct. In your case, the constructor, foo, assigns the value of "i" to the member variable "value".

Then in main you construct a struct foo object, giving it the value 1. In the context, the compiler discovers that you have provided a conversion operator to an int, which it uses to pass to the object to the stream.

So I'm not sure I understand where you think the struct should be linked instead of the function. You can call constructors to make objects. You can't actually call a struct. (unless you make an operator() in it, then you can call that member function of the struct. But you didn't make one of those, so there isn't a meaning to "calling the struct".)

As far as overriding library functions -- Do you have access to the code that you want to call your new function? It wouldn't be confusing to just change the call to be to your new function. If you have to change but can't change the source, you can (often) provide a new function with EXACTLY the same signature in the same set of object modules and it will be used before the linker finds the other version in a library. But what you want is a function, not a struct.

Upvotes: 1

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42929

Justification

According to the C++ standard N4431 § 3.3.10/2 Name hiding [basic.scope.hiding] (emphasis mine):

A class name (9.1) or enumeration name (7.2) can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope. If a class or enumeration name and a variable, data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.

Solution

Put either struct foo or function foo in its own namespace.

Upvotes: 11

Related Questions