C++0x features in VC2010 - auto

Summary Page 

 

(n3090.pdf is the current working draft of C++0x standard, it is available at https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3090.pdf)

What we have before C++0x

C++ is a strongly typed programming language. You have to specify the type when declaring variables. Sometimes it is tedious or even difficult.

To simplify variable declaration, GCC has an extension keyword "__typeof__" and boost provides library implementation "BOOST_TYPEOF" to deduce the type from the initializer.

What we have now in C++0x

"auto" is a keyword in C++03, but it is redundant in most cases.

The standard committee wants to reuse existing keyword and give "auto" new meaning in C++0x (n3090.pdf, 7.1.6.4) .

Here are some typical usages of it.

1. Simplify code.

void test(const map<string, string>& m)

{

#ifdef USEAUTO

    for (auto iter(m.begin()); iter != m.end(); ++iter) {

#else

    for (map<string, string>::const_iterator iter(m.begin());

        iter != m.end(); ++iter) {

#endif

        cout << "The stock symbol of " << iter->first <<

            " is " << iter->second << endl;

    }

}

2. Make generic programming easier.

template<typename Iter>

void foo(Iter iter)

{

#ifdef USEAUTO

    auto t(*iter);

#else

    iterator_traits<Iter>::value_type t(*iter);

#endif

    //...

}

3. Prevent type-mismatch which leads to data truncation.

int x = 0x80000000; // x = -0x80000000

auto y = 0x80000000; // the type of y is unsigned int

4. Declare lambda variable whose type is generated by the compiler and unknown. Otherwise we have to put it into a function object which has runtime overhead.

#ifdef USEAUTO

auto f([](int n){printf("%d\n", n);});

#else

#include <functional>

std::function<void (int)> f([](int n){printf("%d\n", n);});

#endif

5. Other examples.

struct A

{

    const static auto s_n = 1; // int

    void f()

    {

        if (auto n = s_n) // int

        {

            auto p = new auto(0); // int *

            // ...

        }

    }

};

6. "auto" can also be used for function with late-specified return type. For example:

    template <typename T, typename U>

    auto add(T t, U u) const -> decltype(t + u) {

        return t + u;

    }

Known issues / limitations

When the compiler deduces the variable type, it uses the same rule as template argument deduction. However, it doesn’t support full template argument deduction rule. See the following example:

int i;

// OK, p has type "const int *"

// It is the same as the type of "u" in the following template

// when called by "helper(&i)"

// template <class T> void helper(const T *u);

const auto *p = &i;

template<typename T> struct A {};

// error, template argument can't be auto

A<auto> o = A<int>();

Known bugs in VC2010

1. Multiple declarators

https://connect.microsoft.com/VisualStudio/feedback/details/545958

int f();

template<class T> T g();

int main()

{

int a1 = f(), b1 = g<int>(); // OK

auto a2 = f(), b2 = g<int>(); // C3538

}

The bug repros when the type of the initializer is dependent on template argument.

The work around is to put the declarations into two lines:

auto a2 = f();

auto b2 = g<int>();

BTW, the bug should be fixed in a future release of VC.

2. auto on nested lambda

https://connect.microsoft.com/VisualStudio/feedback/details/539810

int main()

{

[]()

{

auto lambda = []()

{

return 42;

};

auto crash = lambda(); // C1001

};

}

There is no workaround for this bug.

BTW, the bug should be fixed in a future release of VC.