#include <iostream>
#include <string>
#include <vector>
// *** before: ***
// the return type had to be written out, and a type that depends on
// the arguments needed the trailing form with decltype
template <class T, class U>
auto addOld(T a, U b) -> decltype(a + b) {
return a + b;
}
std::vector<std::string>::const_iterator firstOld(
const std::vector<std::string>& v) {
return v.begin();
}
// *** in version C++14: ***
template <class T, class U>
auto add(T a, U b) {
return a + b; // the type comes from the return statement
}
auto first(const std::vector<std::string>& v) {
return v.begin();
}
auto& grow(std::vector<int>& v) { // auto alone would drop the reference
v.push_back(1);
return v;
}
decltype(auto) firstItem(std::vector<int>& v) { // keeps int&, not int
return v[0];
}
int main() {
std::cout << addOld(1, 2.5) << " " << add(1, 2.5) << "\n";
std::vector<std::string> words{"one", "two"};
std::cout << *firstOld(words) << " " << *first(words) << "\n";
std::vector<int> v;
firstItem(grow(v)) = 42;
std::cout << v[0] << "\n";
}