c++0x and auto

According to the acronym C++0x, we shouldn’t be waiting for the next language standard more than one year and half. According to the uneasiness I read in the messages from the committee board, maybe the waiting could last slightly more. Anyway the next C++ is about to debut. By reading what is going to pop up in the next standard, I got the strong impression that this is another step away from the original language. Let’s face it, C++ 98 (ISO/IEC 14882:1998) is a first step away from the original, non-standard language that included templates as an afterthought. It took years for compiler vendors to reach compliance, leaving the developer community in a dangerous interregnum, a nobody’s land where portability and maintainability concerns where stronger than writing proper code. Also the standardization process left a number of lame aspects in the language – the iostream library, inconsistencies in the string class and the other containers, a mind boggling i18n support, no complete replacement for C standard library, just to name the firsts that come to mind.
The next standard seems to take a number of actions to plug the holes left in the previous one and a number of actions to define a new and different language. For example there will be a new way to declare functions, that will make appear pale an unoffensive the transition from K&R style to ANSI C. What today is declared as:

int f( char* a, int b )

is going to be declared also as:

[] f( char* a, int b ) -> int

I understand there’s a reason for this, it’s not just out of madness, nonetheless, this is going to puzzle the Joe Average developer. Once the astonishment for the new notation is expired, how is he supposed to declare functions?
The impression I got about C++0x going to be a different language has also been reinforced by a sort of backpedaling on the “implicit” stuff.
C++ has a lot of stuff going on under the hood. Good or bad, you chose, nonetheless you get by default a number of implict stuff, e.g. a set of default methods (default constructor, destructor, copy constructor and assignment operator), and a number of implicit behaviour, such as using constructors with a single argument as conversion constructor.
Now this has been considered no longer apt for the Language, so modifiers to get rid of all this implicit-ness has been introduced. E.g. conversion operators may be declared “explicit” meaning that they will not be used implicitly when an object is evaluated in a suitable context. In a class each single default method can be either disabled:

class Foo
{
    public:
        Foo() = delete;
};

Or explicitly defined as the default behaviour:

class Foo
{
    public:
        Foo() = default;
};

 

 

Again I see the rationale behind this, but I find that changing the rules of the language after 30 years of its inception is going to surprise many a developer.
One of the most welcomed addition in the new standard, at least in my humble opinion, is the new semantic for the auto keyword. If you use the STL part of the standard on a daily base, I’m quite sure you are going to agree. Let’s take for example something like:

std::vector< std::pair<bool,std::string> > bar;

After some manipulation say you want to sweep through the vector with the iterator idiom. You can wear a bit your keyboard by writing the short poem:

for( std::vector< std::pair<bool,std::string>>::iterator i=bar.begin(); i != bar.end(); ++i ) ...

 

 

I usually go for a couple of typedef so that the iterator type can be written more succinctly. The new standard allows the programmer to take a shortcut. If the type of the iterator is defined by the return type of bar.begin() then it could be catch internally and used to declare i. That turns out as:

for( auto i=bar.begin(); i != bar.end(); ++i ) ...

As you see, this is extremely more readable (and writable altogether).
Well, well, well, too bad we have to wait at least one year for the standard and an uncountable number of years before vendors update their compilers. But, if you use GNU C++ then you may not be helpless.
GNU C++ implements the typeof extension. Just like sizeof evaluates to the size of the type resulting from the expression to which it is applied, typeof evaluates to the type resulting from the expression to which it is applied. E.g.:

int i;
typeof( &i ) // evaluates to int*.

(this works much like the decltype keywords of the next C++ standard). Given that the expression to which typeof is applied is not evaluated, then no side effects could happens. And this calls for the handy preprocessor:

#define AUTO(V__,E__) typeof(E__) V__ = (E__)

Now this macro does much the yet-to-come auto keyword does:

for( AUTO(i,bar.begin()); i != bar.end(); ++i ) ...

Note that typeof doesn’t do well with the references, so, in some cases (such as the example below) could behave unexpectedly:

#include
#include

std::string foo( "abc" );

std::string const& f()
{
    return foo;
}

int main()
{
    AUTO( a, f() );
    std::string const& b = foo();
    std::cout << "a=" << a << "n";
    std::cout << "b=" << b << "n";
    foo = "cde";
    std::cout << "a=" << a << "n";
    std::cout << "b=" << b << "n";

    return 0;
}

If your compiler of choice doesn’t support typeof (or decltype), then you have to wait for it to become C++0x compliant.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.