Why doesn't C++ implement construction + calling functions in same line?
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?
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.
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.
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.
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.
精彩评论