C++_STL_Tools - RicoJia/notes GitHub Wiki
========================================================================
========================================================================
-
- ceil, floor
- cos, sin
-
std::equal() 比较两个vector
-
limits
#include <limits> cout << numeric_limits<double>::min() << endl; cout << numeric_limits<double>::max() << endl; double a = std::numeric_limits<double>::infinity(); // > or < both gives you false!
-
!=
is false,==
is true. - (for int you don't have a true infinity
std::numeric_limits<int>max()
; ) - isinf:
#include <cmath> isinf(double)
-
std::numeric_limits<double>::min())
: this is10 e^-308
-
-
std::abs() in only takes in integers, but in it takes in floats. you can use std::fabs() for floating point uses.
- std::abs vs std::fabs
- cmath's abs(-2.5) outputs 2. std::abs will output 2.5, because it has type overload.;
- abs and fabs are there for backward compatibility. So just use std::abs., can be used directly
- std::abs vs std::fabs
-
std::count(beg_itr, end_itr, 'target');
-
std::isnan()
-
std::numeric_limits::quiet_NaN();
-
std::plus
#include <functional> //std::plus //Definition template <typename T> struct plus{ T operator(const T& x, const T& y){ return x + y; } } // Example std::transform(arr1, arr1 + 4, arr2, results, std::plus<int>); //C++ 11 std::transform(arr1, arr1 + 4, arr2, results, std::plus<>); //C++ 14
- standard operator's type can be omitted in C++14, so
std::plus<int> -> std::plus<>
- standard operator's type can be omitted in C++14, so
-
sqrt(1.5)
直接用
-
std::norm(complex<double>{motion_vector.at(i), motion_vector.at(i+1)});
finding squared norm.
========================================================================
========================================================================
-
std::accumulate
acceptable forms:- simple summing
#include <numeric> sum = std::accumulate(vec.begin(), vec.end(), 0.0);
- Note: sum will be casted to int, even if
std::vector<double> vec
:
sum = std::accumulate(vec.begin(), vec.end(), 0);
- Note: sum will be casted to int, even if
- Other accumulative tasks:
T accumulate(Iterator first, Iterator Last, T init, Binary_Operation op){ for(; first != last; ++first){ init = op(std::move(init), *first); } }
- E.g,
std::accumulate(vec.begin(), vec.end(), 1, [](int product, int b){return product*b});
- simple summing
========================================================================
======================================================================== 2. max_element
#include <algorithm>
std::max_element(begin_itr, end_itr, policy)
**注意, 如果vector 自己是空的话,max_element 本身只是返回vec.end(), 但是你要dereference 的话,那么你就会有error!**
-
std::min()
// find min between 2 nums #include <algorithm> std::min(a,b, [](A& a, B&b){return a.something \<\ b.something}; ); // find min in a list std::min({a,b,c...} compare) // returns the smallest in the initializer list!
- std::min(unsigned int, int) is not allowed!
-
*在用partition, transform 等时,你的predicate 的argument是 (itr), 而不是iterator 本身
-
Transform
- unary operations
// Definition transform(Iterator inputBegin, Iterator inputEnd, Iterator OutputBegin, unary_operation) // example: increment a number in an array int arr[] = {1,2,3,4}; n = sizeof(arr)/sizeof(int); std::transform(arr, arr+n, arr, [](int x){return x+1;})
- binary operation
// Definition transform(Iterator inputBegin1, Iterator inputEnd1, Iterator inputBegin2, Iterator outputBegin, binary_operation) // Example: arr_1 - arr 2 int arr_1[] = {1,2,3,4}; int arr_2[] = {1,2,3,4}; int result[5]; std::transform(arr_1, arr_1+4, arr_2, result, [](int i1, i2){return i1 - i2; });
std::transform(It1 it1_begin, It1, it1_end, It2 it2_end, It3 out_begin, [](const Type1& a, const Type2&b){return something})
-
std::swap()
in algorithm -
For each
- std::for_each
#include<algorithm> std::for_each(begin(numbers), end(numbers), [](int num){do stuff});
- for each loop: array will also return a reference/copy!
int arr[] {1,2,3}; for (int x : arr) cout<<x;
-
std::for_each
#include <algorithm> void func (const int& i){}; int main(){ std::vector<int> vec {1,2,3}; std::for_each(vec.begin(), vec.end(), &func); }
-
std::find_if
#include <algorithm> std::vector<int>::iterator it = std::find_if(vec.begin(), vec.end(), if_true);
-
std::partition: reorder elements [beg, end), elements satify the predicate will be put left (inside order NOT preserved). returns the first element of the second group.
#include <algorithm> // Bad Example: auto first_it = std::partition(ls.begin(), ls.end(), [&pivot](const int& i){return i < pivot; }); // is first_it the pivot? Not necessarily, because the order of the right-hand side might be screwed up!
-
std::partition
: all members in that range [) wil be modified, so don't change that range. Internally, it's also blocking.
-
========================================================================
========================================================================
- std::advance
- iterator only? yes.
#include <iterator> std::advance(it, distance);
- what if out of limits?
- if distance < 0, decrement
- If distance out of bounds,undefined behavior
- increment for loop not by ++
for(auto start = id; start < test_vec.size(); start += num_threads){}
- reminder: for(auto i: map) returns a
std::pair
, not iterator! If returning iterator, then you need*it
.
========================================================================
========================================================================
-
std::hash
:#include <functional>
- works well with prime nums?
========================================================================
========================================================================
-
Chrono lib addresses different systems have different clocks, and precision might be different. So it separates duration, and point of time from specific clocks.
- is both the header file and the namespace
- Contains all time-handling facilities used by thread library
- Wall time vs CPU time, and a super good doc
-
clock:
- has:
-
std::chrono::steady_clock
: cannot be adjusted? ticks at mono-rate, like a stop-watch -
std::chrono::system_clock
: same as the one in tool bar, so affected by "day-light saving" -
std::chrono::high_resolution_clock
: smallest possible tick period,high_resolution_clock
may be a synonym forsteady_clock
andsystem_clock
- except for steady_clock, adjustments are applied to accomodate local clock drift. So a call
now()
may return a value earlier than a previousnow()
. (think about multi-threaded case)
-
- class members:
- now (time_point):
time_point <system_clock> start = system_clock::now();
, a static function -
period
: a ratio, tick periodcout<<std::chrono::system_clock::period::num<<" | "<<std::chrono::system_clock::period::den<<endl; // see 1 | 1000000000, // std::ratio must be printed this way
- Except for
std::chrono::steady_clock
, this period is not guaranteed to be the steady period!
- Except for
-
is_steady
cout<<std::chrono::system_clock::is_steady<<endl;
- now (time_point):
- has:
-
duration:
std::chrono::duration<double>
-
std::chrono::milliseconds
,std::chrono::seconds
,std::chrono::hours
- are
duration</*signed integer type of at least 45 bits*/, std::milli>
- are
- Define your own type: - ratio is respective to second
using short_min = std::chrono::duration<short, std::ratio<60,1>> // a min in short int using double_ms = std::chrono::duration<double, std::ratio<1,1000>> // a millisecond in double short_min sm(2); cout <<"sm count "<<sm.count()<<endl; // see 2
- class members:
-
count()
: double for duration, int for milliseconds and othersmilliseconds m(30); cout<<m.count()<<endl; //30
-
time_since_epoch.count()
: returns the number of periods passed, not in seconds!std::cout << "periods: " << dtn.count() << std::endl; std::cout << "seconds: " << dtn.count() * system_clock::period::num / system_clock::period::den; // periods: 1338280396212871 // seconds: 1338280396
-
-
period
, which is astd::ratio
, can be used for conversionm.count() * std::chrono::milliseconds::period::num / std::chrono::milliseconds::period::den //(num for numerator, den for denominator, ALL IN INT, here this ratio is 1:1000, so RELATIVE TO SECONDS)
- arithmatic:
30*std::chrono::seconds(1); //equivalent to std::chrono::seconds(30) minutes(1) - seconds(55); // get seconds(5)
-
-
conversions:
- seconds -> timepoint:
std::chrono::system_clock::time_point tp{std::chrono::seconds{timeSeconds}};
- hours -> seconds, implicit, no explicit conversion required.
- timepoint cast:
auto start_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(start_).time_since_epoch().count();
- From seconds to hours, needs explicit conversion using
duration_cast
, and will be truncatedstd::chrono::milliseconds ms(54802); std::chrono::seconds s = std::chrono::duration_cast<std::chrono::seconds>(ms); cout<<s.count()<<endl; //see 54
- time_since_epoch -> time in seconds (python's
time.time()
): seconds from epoch in doublecout<<std::chrono::duration_cast<seconds>(system_clock::now().time_since_epoch()).count() / 1.0 <<endl;
- duration -> time in double:
duration<double> time_stamp = system_clock::now().time_since_epoch(); payload["timestamp"] = time_stamp.count();
- seconds -> timepoint:
-
std::chrono::time_point<std::chrono::system_clock>
- difference must be
std::duration<double>
std::chrono::time_point<std::chrono::system_clock> start, end; start = std::chrono::system_clock::now(); end = std::chrono::system_clock::now(); std::chrono::duration<double> diff1 = end - start; std::chrono::duration<int> diff2 = end - start; //ERROR: not defined cout<<"elapsed time in seconds: "<<diff1.count()<<endl;
std::chrono::duration<int> = time_point::time_since_epoch()
-
std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>
returns duration in minutes - can do
std::chrono::high_resolution_clock::now() + std::chrono::seconds(500)
- difference must be
-
std::time_t
: almost (not guaranteed) that will hold number of seconds since epochstd::time_t end_time = std::chrono::system_clock::to_time_t(end); // see 1629678991
- get formatted time:
std::string get_formatted_time(const time_point<system_clock>& t) { // the format is like 23-Aug-2021-22-41-10 time_t int_time = system_clock::to_time_t(t); tm* local_time = localtime(&int_time); char buffer[80]; strftime(buffer, 80, "%d-%b-%Y-%H-%M-%S", local_time); return buffer; }
-
std::ctime(std::time_t*)
cout<<std::ctime(&end_time)<<endl; //Mon Aug 23 00:53:41 2021
-
there are SI ratios:
-
std::atto
10^-18 -
std::exa
10^18
-
-
Profile Timer - no "correct way", just what ppl use:
struct Profiler_Timer{ Profiler_Timer(const std::string& name = ""): name_(name){ start_ = std::chrono::high_resolution_clock::now(); } ~Profiler_Timer(){ auto end = std::chrono::high_resolution_clock::now(); auto start_us = std::chrono::time_point_cast<std::chrono::microseconds>(start_).time_since_epoch().count(); auto end_us = std::chrono::time_point_cast<std::chrono::microseconds>(end).time_since_epoch().count(); std::cout<<name_<<"finishes in "<< (end_us - start_us)/1000000.0<<"s"<<endl; } std::chrono::time_point<std::chrono::high_resolution_clock> start_; std::string name_; };
========================================================================
========================================================================
-
Classic Literals
42 //int 2.4 //double 3.2F //float 'w' //char 32ULL //unsigned long long 0xD0 //Hex "cd" //c-style string
-
std::literals
: No underscores- "Hello"s, std::string literal (not c-string literal!, C++14)
#include <iostream> cout<<"Hello"s;
- 0b10: a binary number literal
cout<<0b10; //you get 2;
- complex 5i
using namespace std::complex_literals; std::complex<double> z4 = 1.0 + 2i; //ONLY double + 2i, no int!! std::cout << z4<< '\n';
- std::chrono_literals: (C++14), Have to have using namespace std::chrono_literals
- 5h, std::chrono::hours
- 5min
- 5s
- E.g
#include<chrono> int main(){ using namespace std::chrono_literals; cout<<1h/30min; //you'll get 2 std::this_thread::wait_for(40ms); }
- "Hello"s, std::string literal (not c-string literal!, C++14)
-
User Defined Literals: UDL
long double operator"" _kg(long double x){return 1000*x;} long double operator"" _g(long double x){return x;} long double weight = 3.6_kg; 3.6_kg/2_g;
- only suffix form is supported for UDL (e.g, _kg)
- UDL is treated as a call to the literal operator ""