0

In this article in the Supporting Parameters by Reference section, they point out the problem with and provide the solution to references. My question is: why don't they just declare the parameters as references in the first place? I.e., instead of:

const Parm parm_;

do:

Parm &parm_;
Paul J. Lucas
  • 6,895
  • 6
  • 44
  • 88
  • Note: this is Go `defer` statement in hiding :) In C++, it's cumbersome, but in C++0x, because of **lambdas** all this talk about argument issues vanish. – Matthieu M. May 08 '11 at 17:57

3 Answers3

0

Because the problem with references was only a one example of how scopeguard could be used. But it should work (and work correctly) in all other cases. So having this clean up function:

void my_exit(const std::string & msg)
{
    std::cout << "my_exit: " << msg << std::endl;
}

This should work (passing temporary object):

void test()
{
    std::string msg("test_1 Hello World");
    ON_BLOCK_EXIT(&my_exit, msg.substr(0, 6));
}

This should work (passing a reference to an object that will be destroyed before the scopeguard is called):

void test()
{
    std::map<int, std::string> m;
    m[42] = "test_2";
    ON_BLOCK_EXIT(my_exit, m[42]);

    m.clear();
}

And this should work (passing a const reference):

void test(const std::string & msg)
{
    ON_BLOCK_EXIT(&my_exit, msg);
}

If the parm was const or non-const reference then those examples would either not compile or crashed when run.

danadam
  • 3,350
  • 20
  • 18
0

It would have to be

const Param &param_;

to allow for the general case and then you would run into the same problem with trying to decrement, or in some other way modify, the parameter. The other option would be to create a lot more classes to handle const and non-const versions.

Using a reference would prevent using the result of an expression as param since the temporary reference created as the function parameter would go out of scope immediately.

Though he could remove all the const's and let it be part of the type and not allow expressions, I think there is still great value in requiring ByRef to aid in clarity.

IronMensan
  • 6,761
  • 1
  • 26
  • 35
  • Why do you need const versions? Isn't the point to be able to update something like a variable or an object? If so, then it can't be const anyway. If you look at the ObjScopeGuardImpl classes, they have an Obj&. – Paul J. Lucas May 09 '11 at 14:14
  • @Paul Your function object doesn't need to be const, but you should accomidate const paremeters to the function object. Pretend the AddFriend method in the article took a const User& instead of how it is listed and also pretend that friends_ is a set, not a vector. You would need to use the form of ScopeGuard with a non-const reference to friends_, the erase pointer-to-member-function and a const reference to newFriend. – IronMensan May 09 '11 at 15:22
0

There is one issue: in C++ temporaries cannot be bound to references, but only to const references.

Therefore, the following cannot be written:

int foo();

int& i = foo();

Unless you use Visual C++ which allows it as an extension to the language.

Also, if I used a function which returns a const reference, then it would not work either.

There is no simple solution here :)

At least not until C++0x lambdas are brought into the picture.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • @Mattieu: Isn't the point to be able to update something like a variable or an object? How can you update a temporary expression? – Paul J. Lucas May 09 '11 at 14:11
  • @Paul J. Lucas: the point of binding is to extend the lifetime of the object. Note that you would not update a temporary expression, but its result. – Matthieu M. May 09 '11 at 14:33
  • But its result is either also a temporary (in which case it's pointless to update it since it will shortly be destroyed) or it's a pointer or reference to some other object (in which case "Parm &param_ would be just fine). No? – Paul J. Lucas May 09 '11 at 14:46
  • @Paul J. Lucas: while it may be shortly destroyed, it could still do plenty of interesting things, things for which state mutation are necessary. This really feels like an arbitrary limitation. – Matthieu M. May 09 '11 at 15:57