-5

How would one go about calling a function by pointer without using the ampersand in the function call where I pass in a struct. I can only edit the function definition, not the way the function is being called. Call by reference can be used, but I would like to call by pointer, is there any way of doing this?

void Some_Func(struct TheStruct &My_struct){
     My_struct->member = 4;  // Would like to do this! 
}

int main(){
Some_Func(My_Struct);
}
marjak
  • 93
  • 7
  • 5
    XY problem again. Why do you want a pointer so much? – Jean-François Fabre Nov 22 '16 at 21:59
  • 2
    Why? What's wrong with writing `My_struct.member = 4;`? – user207421 Nov 22 '16 at 21:59
  • Is your keyboard lacking the ampersand sign or why don't you want to use it? Maybe have a look here: https://www.google.de/search?q=cheap+keyboard&ie=utf-8&oe=utf-8&client=firefox-b-ab&gfe_rd=cr&ei=1b80WLzNIs7j8wel0J-4Ag#q=cheap+keyboard&tbm=shop&spd=5151555981146022932 – Kijewski Nov 22 '16 at 22:00
  • @Jean-FrançoisFabre It was asked by my senior, without touching the way it is being called. I do not think it is possible and that call by reference needs to be used. – marjak Nov 22 '16 at 22:01
  • 3
    your senior has 3 downvotes right now :) – Jean-François Fabre Nov 22 '16 at 22:02
  • 1
    put `#define Some_Func(c) Some_Other_Func(&c)` somewhere. – Jean-François Fabre Nov 22 '16 at 22:07
  • 2
    @Jean-FrançoisFabre, don't forget to put parens around the any macro parameter! ;) Also, interestingly enough `#define SomeFunc(X) SomeFunc(&(X))` works fine. The macro does not expand itself. – Kijewski Nov 22 '16 at 22:09
  • 1
    @Kay yes, or it would be highly incorrect and that would be too bad since my macro is utterly useful ! Fortunately you cannot downvote my comment :) – Jean-François Fabre Nov 22 '16 at 22:11
  • 1
    Saying 'my senior told me so' doesn't really answer the question. Ask *him* why. You're not a robot. – user207421 Nov 22 '16 at 22:13
  • You can even do `#define Some_Func(c) Some_Func(&(c))` to (mis)use the same function name ;) – EmDroid Nov 22 '16 at 22:13
  • 2
    @axalis, yes, Kay already mentionned that. That was my first "attempt" but I rolled it back. At least I learned a few things with this post. I'm almost tempted to upvote it. Wait. Noooooo. Hey someone _did_ upvote it :) Hey there are 245+ answers, the post cannot be _that_ bad. – Jean-François Fabre Nov 22 '16 at 22:16
  • Your line of code 'would like do this' is not an example of calling a function by pointer, and therefore does not agree with either your title or the body of your question. The title and the body of the question both embody contradictions in terms. Unclear what you're asking. – user207421 Nov 22 '16 at 22:26
  • @Jean-FrançoisFabre Thanks alot, That macro trick seems to be giving me a problem in my function definition when I declare the void function. Do I still need to include a prototype if I use the #define? I get the error "variable has incomplete type void" and "Expected expression" errors. Any idea why? – marjak Nov 23 '16 at 20:09

4 Answers4

2

I am 90% sure this is not the answer you are looking for, but I'll post it for the remaining 10% of doubt anyway:

Have a look at std::addressof(T&). It gives you the pointer without using an ampersand.

Kijewski
  • 25,517
  • 12
  • 101
  • 143
2

To be honest, I think this question was triggered by some misunderstanding....Lets assume you have this (working) code:

struct TheStruct { int member;};
void Some_Func(struct TheStruct &My_struct){
     // some implementation
}

int main(){
    TheStruct x;
    Some_Func(x);
}

You say

I can only edit the function definition, not the way the function is being called.

...thus there is no way to make the function take a pointer as parameter. If there is a instance (not a pointer) passed as parameter in main and you are not allowed to change main, then you cannot magically make the parameter a pointer.

The only way to use -> inside the function is

void Some_Func(struct TheStruct &My_struct){
    TheStruct* x = &MyStruct;
    x->member = 4;
}

However, there is not a single reason to do so (unless the . on your keyboard is broken) and it makes the code confusing to read.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
2

When accessing an object by reference, you have to use the . operator to reach its members:

void Some_Func(TheStruct &My_struct) {
    My_struct.member = 4;
}

int main() {
    TheStruct My_struct;
    Some_Func(My_Struct);

    // or:
    // TheStruct *My_struct = new My_struct;
    // Some_Func(*My_Struct);
    // delete My_struct;
}

When accessing an object by pointer, you have to use the -> or *. operator to reach its members:

void Some_Func(TheStruct *My_struct) {
    My_struct->member = 4;
    // or (*My_struct).member = 4;
}

int main() {
    TheStruct My_struct;
    Some_Func(&My_Struct);

    // or:
    // TheStruct *My_struct = new TheStruct;
    // Some_Func(My_Struct);
    // delete My_struct;
}

If you don't want to use the & operator to get the address of an object variable (maybe because it overrides operator&, for instance), you can use std::addressof() in C++11 and later:

int main() {
    TheStruct My_struct;
    Some_Func(std::addressof(My_Struct));
}

Or use boost::addressof:

#include <boost/utility.hpp>

int main() {
    TheStruct My_struct;
    Some_Func(boost::addressof(My_Struct));
}

Or implement addressof() manually:

template<class T>
T* my_addressof(T& arg) 
{
    return reinterpret_cast<T*>(
        &const_cast<char&>(
            reinterpret_cast<const volatile char&>(arg)
        )
    );
}

int main() {
    TheStruct My_struct;
    Some_Func(my_addressof(My_Struct));
}
Community
  • 1
  • 1
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

This will work.

struct TheStruct {
    int member;
};

void Some_Func(TheStruct &My_struct){
    My_struct.member = 4;
}

int main(){
    TheStruct My_Struct;

    My_Struct.member = 5;
    std::cout << My_Struct.member << std::endl;

    Some_Func(My_Struct);
    std::cout << My_Struct.member << std::endl;

    return 0;
}

Output:

5

4

fonZ
  • 2,428
  • 4
  • 21
  • 40