update
This commit is contained in:
21
learn_class/modern_C++_30/container1/container.cpp
Normal file
21
learn_class/modern_C++_30/container1/container.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Created by light on 19-12-16.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "output_container.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
map<int, int> mp{
|
||||
{1, 1}, {2, 4}, {3, 9}};
|
||||
cout << mp << endl;
|
||||
vector<vector<int>> vv{
|
||||
{1, 1}, {2, 4}, {3, 9}};
|
||||
cout << vv << endl;
|
||||
|
||||
}
|
148
learn_class/modern_C++_30/container1/output_container.h
Normal file
148
learn_class/modern_C++_30/container1/output_container.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Written by Wu Yongwei <wuyongwei AT gmail DOT com>.
|
||||
*
|
||||
* Using this file requires a C++17-compliant compiler.
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OUTPUT_CONTAINER_H
|
||||
#define OUTPUT_CONTAINER_H
|
||||
|
||||
#include <ostream> // std::ostream
|
||||
#include <type_traits> // std::false_type/true_type/decay_t/is_same_v
|
||||
#include <utility> // std::declval/pair
|
||||
|
||||
// Type trait to detect std::pair
|
||||
template <typename T>
|
||||
struct is_pair : std::false_type {};
|
||||
template <typename T, typename U>
|
||||
struct is_pair<std::pair<T, U>> : std::true_type {};
|
||||
template <typename T>
|
||||
inline constexpr bool is_pair_v = is_pair<T>::value;
|
||||
|
||||
// Type trait to detect whether an output function already exists
|
||||
template <typename T>
|
||||
struct has_output_function {
|
||||
template <class U>
|
||||
static auto output(U* ptr)
|
||||
-> decltype(std::declval<std::ostream&>() << *ptr,
|
||||
std::true_type());
|
||||
template <class U>
|
||||
static std::false_type output(...);
|
||||
static constexpr bool value =
|
||||
decltype(output<T>(nullptr))::value;
|
||||
};
|
||||
template <typename T>
|
||||
inline constexpr bool has_output_function_v =
|
||||
has_output_function<T>::value;
|
||||
/* NB: Visual Studio 2017 (or below) may have problems with
|
||||
* has_output_function_v<T>: you should then use
|
||||
* has_output_function<T>::value instead, or upgrade to
|
||||
* Visual Studio 2019. */
|
||||
|
||||
// Output function for std::pair
|
||||
template <typename T, typename U>
|
||||
std::ostream& operator<<(std::ostream& os, const std::pair<T, U>& pr);
|
||||
|
||||
// Element output function for containers that define a key_type and
|
||||
// have its value type as std::pair
|
||||
template <typename T, typename Cont>
|
||||
auto output_element(std::ostream& os, const T& element,
|
||||
const Cont&, const std::true_type)
|
||||
-> decltype(std::declval<typename Cont::key_type>(), os);
|
||||
// Element output function for other containers
|
||||
template <typename T, typename Cont>
|
||||
auto output_element(std::ostream& os, const T& element,
|
||||
const Cont&, ...)
|
||||
-> decltype(os);
|
||||
|
||||
// Main output function, enabled only if no output function already exists
|
||||
template <typename T,
|
||||
typename = std::enable_if_t<!has_output_function_v<T>>>
|
||||
auto operator<<(std::ostream& os, const T& container)
|
||||
-> decltype(container.begin(), container.end(), os)
|
||||
{
|
||||
using std::decay_t;
|
||||
using std::is_same_v;
|
||||
|
||||
using element_type = decay_t<decltype(*container.begin())>;
|
||||
constexpr bool is_char_v = is_same_v<element_type, char>;
|
||||
if constexpr (!is_char_v) {
|
||||
os << "{ ";
|
||||
}
|
||||
if (!container.empty()) {
|
||||
auto end = container.end();
|
||||
bool on_first_element = true;
|
||||
for (auto it = container.begin(); it != end; ++it) {
|
||||
if constexpr (is_char_v) {
|
||||
if (*it == '\0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if constexpr (!is_char_v) {
|
||||
if (!on_first_element) {
|
||||
os << ", ";
|
||||
} else {
|
||||
on_first_element = false;
|
||||
}
|
||||
}
|
||||
output_element(os, *it, container, is_pair<element_type>());
|
||||
}
|
||||
}
|
||||
if constexpr (!is_char_v) {
|
||||
os << " }";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename T, typename Cont>
|
||||
auto output_element(std::ostream& os, const T& element,
|
||||
const Cont&, const std::true_type)
|
||||
-> decltype(std::declval<typename Cont::key_type>(), os)
|
||||
{
|
||||
os << element.first << " => " << element.second;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename T, typename Cont>
|
||||
auto output_element(std::ostream& os, const T& element,
|
||||
const Cont&, ...)
|
||||
-> decltype(os)
|
||||
{
|
||||
os << element;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
std::ostream& operator<<(std::ostream& os, const std::pair<T, U>& pr)
|
||||
{
|
||||
os << '(' << pr.first << ", " << pr.second << ')';
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif // OUTPUT_CONTAINER_H
|
64
learn_class/modern_C++_30/container1/vector_l.cpp
Normal file
64
learn_class/modern_C++_30/container1/vector_l.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// Created by light on 19-12-16.
|
||||
//
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
using namespace std;
|
||||
|
||||
class Obj1 {
|
||||
public:
|
||||
Obj1()
|
||||
{
|
||||
cout << "Obj1()\n";
|
||||
}
|
||||
Obj1(const Obj1&)
|
||||
{
|
||||
cout << "Obj1(const Obj1&)\n";
|
||||
}
|
||||
Obj1(Obj1&&)
|
||||
{
|
||||
cout << "Obj1(Obj1&&)\n";
|
||||
}
|
||||
};
|
||||
|
||||
class Obj2 {
|
||||
public:
|
||||
Obj2()
|
||||
{
|
||||
cout << "Obj2()\n";
|
||||
}
|
||||
Obj2(const Obj2&)
|
||||
{
|
||||
cout << "Obj2(const Obj2&)\n";
|
||||
}
|
||||
Obj2(Obj2&&) noexcept
|
||||
{
|
||||
cout << "Obj2(Obj2&&)\n";
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
vector<int> v;
|
||||
|
||||
int nums = 20;
|
||||
for (int i = 0; i < nums; ++i) {
|
||||
v.push_back(i + 1);
|
||||
cout << "v_size: " << v.size() << "\t v_capacity: " << v.capacity() << endl;
|
||||
}
|
||||
// 头两个在已有空间上成功构造。第三个时发现空间不足,系统会请求更大的空间,大小由实现决定(比如两倍)。
|
||||
// 有了足够的空间后,就会在新空间的第三个的位置构造(第三个obj1),成功之后再把头两个拷贝或移动过来。
|
||||
vector<Obj1> v1;
|
||||
// v1.reserve(2);
|
||||
v1.emplace_back();
|
||||
v1.emplace_back();
|
||||
v1.emplace_back();
|
||||
v1.emplace_back();
|
||||
|
||||
vector<Obj2> v2;
|
||||
v2.reserve(2);
|
||||
v2.emplace_back();
|
||||
v2.emplace_back();
|
||||
v2.emplace_back();
|
||||
}
|
Reference in New Issue
Block a user