views:

271

answers:

7

I'm learning c++0x, at least the parts supported by the Visual C++ Express 2010 Beta. This is a question about style rather than how it works. Perhaps it's too early for style and good practice to have evolved yet for a standard that isn't even released yet...

In c++0x you can define the return type of a method using -> type at the end of the function instead of putting the type at the start. I believe this change in syntax is required due to lambdas and some use cases of the new decltype keyword, but you can use it anywhere as far as I know.

// Old style 
int add1(int a, int b)
{
 return a + b;
}

// New style return type
auto add2(int a, int b) -> int
{
 return a + b;
}

My question really then, is given that some functions will need to be defined in the new way is it considered good style to define all functions in this way for consistency? Or should I stick to only using it when necessary?

+18  A: 

Do not be style-consistent just for being consistent. Code should be readable, i.e. understandable, that's the only real measure. Adding clutter to 95% of the methods to be consistent with the other 5%, well, that just does not sound right to me.

gimpf
Accepted this answer as it sums up the discussion and has the most up votes anyway. The other answers are all good though, thanks
John Burton
+2  A: 

Seems to me like it would be changing the habit of a lifetime for a lot of C++ (and other C like) programmers.

If you used that style for every single function then you might be the only one doing it :-)

frou
+5  A: 

There is a huge codebase that uses the 'old'/current rules. I would bet that is going to be so for a long time. The problem of consistency is two-fold: who are you going to be consistent with, the few code that will require the new syntax or all existing code?

I will keep with the old syntax when the new one is not required for a bit, but then again, only time will tell what becomes the common usage.

Also note that the new syntax is still a little weird: you declare the return type as auto and then define what auto means at the end of the signature declaration... It does not feel natural (even if you do not compare it with your own experience)

David Rodríguez - dribeas
+2  A: 

I am going to guess that the current standard will win out, as it has so far with every other proposed change to the definition. It has been extended, for sure, but the essential semantics of C++ are so in-grained that I don't think they are worth changing. They have influenced so many languages and style guides its ridiculous.

As to your question, I would try and separate the code into modules to make it clear where you are using old style vs new style. Where the two mix I would make sure and delineate it as much as possible. Group them together, etc.

[personal opinion]I find it really jarring to surf through files and watch the style morph back and forth, or change radically. It just makes me wonder what else is lurking in there [/personal opinion]

GrayWizardx
+5  A: 

Personally, I would use it when it is necessary. Just like this-> is only necessary when accessing members of a base class template (or when they are otherwise hidden), so auto fn() -> type is only necessary when the return type can't be determined before the rest of the function signature is visible.

Using this rule of thumb will probably help the majority of code readers, who might think "why did the author think we need to write the declaration this way?" otherwise.

Charles Bailey
+1  A: 

Good style changes -- if you don't believe me, look at what was good style in 98 and what is now -- and it is difficult to know what will considered good style and why. IMHO, currently everything related to C++0X is experimental and the qualification good or bad style just doesn't apply, yet.

AProgrammer
+5  A: 

I don't think it is necessary to use it for regular functions. It has special uses, allowing you to do easily what might have been quite awkward before. For example:

template <class Container, class T>
auto find(Container& c, const T& t) -> decltype(c.begin());

Here we don't know if Container is const or not, hence whether the return type would be Container::iterator or Container::const_iterator (can be determined from what begin() would return).

visitor