tags:

views:

185

answers:

4

I'm wondering why C++ (and possibly other languages, I'm not sure) doesn't allow statements like this.

MyObject foo.DoBar();

You would think that the language could understand to construct the object, then call the function. The only reason I can think of this not working is that if the construction of the object failed, the statement would still try to call the function.

What are the reasons why those who help develop and integrate new features into C++ (and possibly other languages) don't allow this?

+3  A: 

I think a better question is why should it? After all:

MyObject foo;
foo.DoBar();

Is hardly any more difficult. It's more readable too (though obviously that may be biased.) Even if you could construct-call, it would likely be tagged as a "bad thing" to do. Sort of how like multiple declarations on the same line are allowed, but often decrease readability.

Such a construct adds rules and complexity to an already complex language, when an arguably preferable solution is already present. Do we really want to add costly sugar to a language just to save a few keystrokes?

In response to:

"I could see it being useful though when you want to construct an object and just call one function on it. "

If you want to construct an object just to call a function, would it be possible to just make that function a free-function? After all, it's operating either on default data or data that was passed to the constructor anyway. The only thing missing would be the destructor.

Not to mention the other option:

struct MyObject
{
    MyObject(bool pCallDoBar = true)
    {
        if (pCallDoBar)
            DoBar();
    }

    void DoBar(void)
    {
    }
};

MyObject foo;

Or just:

MyObject().DoBar(); // destructor called here, though

I think you'd need a concrete example to really make a case.

GMan
I could see it being useful though when you want to construct an object and just call one function on it. However, I definitely see where you are coming from in terms of readability, and in most cases I agree.
Anonymous
If you are constructing an object and calling one function on it, then you can do `MyObject().foo()`.
jamesdlin
@james: D'aw, you beat me :] The only problem is that "loses" the destructor, if the name needed to stick around. (Think mutex.)
GMan
@GMan: I assume you're referring to the fact that `MyObject().foo()` calls the destructor at the end of the expression rather than the end of the enclosing scope for `MyObject foo;`.
David Thornley
@David: yupyup.
GMan
A: 

Well here's a problem: What if foo needs to use a non-default constructor. Now it's

MyObject foo(arg1, arg2).DoBar();

This is kind of messy and really isn't much better than

MyObject foo(arg1, arg2);
foo.DoBar();

Remember: Code should be easily understandible!

Note that, it's sort of possible to do what you want, if DoBar returns a reference to *this:

MyObject foo = MyObject().DoBar();

With C++0x move constructors, this will entail little overhead, but until then, expect a spurious copy.

rlbond
+13  A: 

You can construct an object and immediately call a function on it, you just can't assign the object to a variable if you do so:

MyObject().DoBar();

A practical reason for this restriction is that the constructor creates the object and the function you're calling could also have a return value, so that you would end up with two values produced by the same statement. Then you would need some special syntax to assign both of these values to variables, something that doesn't happen anywhere else.

And the little convenience that might be gained by directly calling the method isn't that big of an advantage that it would be worth introducing new syntax for it.

sth
+1 for the correct reasons. BTW, is it a recent trend in SO of OP's accepting answers without upvoting?
Abhay
I like this syntax: "MyObject foo().setConfidential().setAsynchrone()", I find it's easier to use than a bunch of constructors variations that only plague the poor user.
Matthieu M.
@Abhay. Non registered users can't upvote.
Anonymous
@Random: Yes, new users can't upvote. But I'm happy to notify you that by now you have already collected enough reputation to upvote, flag posts and comment on other peoples questions/answers :).
sth
@Matthieu: You can string state mutators in the line after the declaration. I don't think that's a real problem.
David Thornley
@David: yes, fortunately. Or can you use a false assignment `MyObject foo = MyObject().set();` though I wonder if it's correctly optimized.
Matthieu M.
@sth I assure you, I can't upvote because I am not registered or logged in. You must be registered or logged in to use voting, neither of which I am.
Anonymous
+2  A: 

In your last paragraph, you're referring to the C++ standards committee. It's been plenty busy, and important language features do get dropped because the committee runs out of time (such as std::unordered_map in the current standard and concepts in the upcoming one). They aren't interested in making minor changes without good reason. In the days before the standards committee, Bjarne Stroustrup wasn't interested in adding minor features just for the sake of having them.

C didn't have this declaration, possibly because nobody wanted it (few people declared types with associated functions back then), possibly because it might be confusing. A lot of features of computer languages are there for historical purposes, and may indicate that somebody made a random choice decades ago. That doesn't mean it's a good idea to change them without good reason, once they're established.

The correct question is not "why don't they make this change?" but "why should they make this change?" Your proposed change doesn't look like it would be really useful, since I can do the exact same thing with two lines of code; total additional typing is one semicolon, one end-of-line, and repetition of the variable name.

The downside is that it would add additional syntax to the language, and it raises the question of return values (as sth pointed out). Should the return value of the called function be discarded? Should the called function be required to return void or some variation on this? Any solution I can see right now is going to be confusing under some circumstances, and whatever C++ needs it isn't more opportunity to get confused.

David Thornley