Изменения в новых версиях / C++14

#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 Tclass 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 Tclass 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();
}

autogrow(std::vector<int>& v) {  // auto alone would drop the reference
    v.push_back(1);
    return v;
}

decltype(autofirstItem(std::vector<int>& v) {   // keeps int&, not int
    return v[0];
}

int main() {
    std::cout << addOld(12.5) << " " << add(12.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";
}