Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
(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