/** @file @brief C++14 @defgroup CPP14 C++14 examples https://en.wikipedia.org/wiki/C++14 https://isocpp.org/wiki/faq/cpp14-language https://github.com/AnthonyCalandra/modern-cpp-features/blob/master/CPP14.md @{ */ static_assert(__cplusplus == 201402, ""); #include using namespace std; /** @defgroup ded14 Deduction @{ */ #define static_assert(a) static_assert(a, "") static_assert(__cpp_return_type_deduction); auto implicit_int_return_type() { return 1; } // template T before_deduced_return_type(int a) { return a; } auto deduced_return_type(int a) { return a; } // template T& before_deduced_return_type_template(T& a) { return a; } template auto& deduced_return_type_template(T& t) { return t; } // Returns a reference to a deduced type. auto deduced_return_type_lambda = [](auto& x) -> auto& { return deduced_return_type_template(x); }; void return_type_deduction_demo() { implicit_int_return_type(); auto x = deduced_return_type(1); int& y = deduced_return_type_lambda(x); // reference to `x` assert(&y == &x); assert(y == 1); } /// @} /** @defgroup other14 Other @{ TODO: https://en.cppreference.com/w/cpp/container/map/find https://en.cppreference.com/w/cpp/language/constexpr https://en.cppreference.com/w/cpp/language/integer_literal https://en.cppreference.com/w/cpp/language/function // decltype(auto) https://en.cppreference.com/w/cpp/language/aggregate_initialization https://en.cppreference.com/w/cpp/thread/shared_timed_mutex https://en.cppreference.com/w/cpp/thread/shared_lock https://en.cppreference.com/w/cpp/utility/integer_sequence https://en.cppreference.com/w/cpp/utility/exchange https://en.cppreference.com/w/cpp/utility/forward https://en.cppreference.com/w/cpp/io/manip/quoted // [[deprecated]] */ /// Binary literals, digit separators /// Template variables /// https://en.cppreference.com/w/cpp/language/variable_template static_assert(__cpp_variable_templates); /// Numeric pi template T pi = T(3.141592653589793238462643383); // String pi // Usual specialization rules apply: template <> const char* pi = "pi"; static void demo() { assert(pi == 3); assert(string(pi) == "pi"); auto binary_literal = 0b0100'1100'0110; auto integer_literal = 1'000'000; auto floating_point_literal = 0.000'015'3; /// Standard user-defined literals auto str = "hello world"s; // auto deduces string auto dur = 60s; // auto deduces chrono::seconds } void types_14() { static_assert(is_null_pointer::value); static_assert(is_null_pointer::value); static_assert(__cpp_decltype); static_assert(is_integral()); // Tuple addressing via type tuple tuple_by_type("foo", "bar", 7); int i = get(tuple_by_type); assert(i == 7); int j = get<2>(tuple_by_type); assert(j == 7); // https://en.cppreference.com/w/cpp/language/auto int a = 0; static_assert(__cpp_decltype_auto); decltype(auto) a_copy = a; assert(&a_copy != &a); decltype(auto) a_ref = (a); assert(&a_ref == &a); // https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique // auto u = unique_ptr(new int(1)); auto u = make_unique(1); assert(u); assert(*u == 1); auto ua = make_unique(3); } /// @} /** @defgroup lambda14 Lambda https://en.cppreference.com/w/cpp/language/lambda @{ */ static void lambda_14() { // Generic lambdas // auto before_generic_lambda = [](int x) { return x; }; static_assert(__cpp_generic_lambdas); auto generic_lambda = [](auto x) { return x; }; auto universal_size = [](const auto& m) { return m.size(); }; static_assert(__cpp_init_captures); auto capture_initializers = [value = 1] { return value; }; assert(capture_initializers() == 1); auto mutable_lambda = [value = 1]() mutable { return ++value; }; assert(mutable_lambda() == 2); assert(mutable_lambda() == 3); // capture initialization can change context int c = 0; auto change_c = [value = ++c] {}; assert(c == 1); unique_ptr ptr(new int(10)); auto capture_by_move = [value = move(ptr)] { return *value; }; } /// Compare with @ref lambda::sort_11 void sort_14() { array s = { 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 }; sort(s.begin(), s.end(), // sort using a generic lambda expression [](auto a, auto b) // C++14 allows auto { return a > b; }); // https://stackoverflow.com/questions/18045208/override-mapcompare-with-lambda-function-directly auto reverse = map> { [](const auto& a, const auto& b) { return a > b; } } = { { "a", 2 }, { "b", 1 }, { "c", 0 }, }; assert(reverse.begin()->first == "c"); assert(reverse.begin()->second == 0); } /// @} int main(void) { return_type_deduction_demo(); demo(); sort_14(); types_14(); lambda_14(); } /// @}