C++0x features in VC2010 - auto
(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.
Comments
- Anonymous
May 08, 2010
Thaxxx I need It