# std::minmax
std::min๊ณผ std::max๋ ๋ง์ด ์จ๋ดค์ง๋ง std::minmax๋ ์จ๋ณด์ง ์์๋ค. ์ฌ์ฉ ๋ฐฉ๋ฒ์ ์ฌํํ๋ค. std::minmax๋ std::pair๋ฅผ ๋ฐํํ๋๋ฐ, ์ฒซ ๋ฒ์งธ๊ฐ ์ต์๊ฐ, ๋ ๋ฒ์งธ๊ฐ ์ต๋๊ฐ์ด๋ค.
min, max, minmax ๋ชจ๋ ๋ํดํธ ์ฐ์ฐ์๋ '<'์ด์ง๋ง predicate๋ฅผ ํ์ฉํด์ ๋ค๋ฅธ ๋น๊ต ์ฐ์ฐ์๋ฅผ ์ง์ ํ ์๋ ์๋ค.
#include <algorithm>
#include <cmath>
#include <iostream>
#include <string>
int main(){
std::cout << std::endl;
std::string first{"first"};
std::string second{"second"};
auto minInt= std::min({3, 1, 2011, 2014, -5});
std::cout << "std::min(2011, 2014): " << std::min(2011, 2014) << std::endl;
std::cout << "std::min(first, second): " << std::min(first, second) << std::endl;
std::cout << "std::min({3, 1, 2011, 2014, -5}): " << std::min({3, 1, 2011, 2014, -5}) << std::endl;
std::cout << "std::min(-10, -5, [](int a, int b){return std::abs(a) < std::abs(b);}): " <<
std::min(-10, -5, [](int a, int b){return std::abs(a) < std::abs(b);}) << std::endl;
std::cout << std::endl;
std::cout << "std::max(2011, 2014): " << std::max(2011, 2014) << std::endl;
std::cout << "std::max(first, second): " << std::max(first, second) << std::endl;
std::cout << "std::max({3, 1, 2011, 2014, -5}): " << std::max({3, 1, 2011, 2014, -5}) << std::endl;
std::cout << "std::max(-10, -5, [](int a, int b){return std::abs(a) < std::abs(b);}): " <<
std::max(-10, -5, [](int a, int b){return std::abs(a) < std::abs(b);}) << std::endl;
std::cout << std::endl;
auto pairInt= std::minmax(2011, 2014);
auto pairStr= std::minmax(first, second);
auto pairSeq= std::minmax({3, 1, 2011, 2014, -5});
auto pairAbs= std::minmax({3, 1, 2011, 2014, -5}, [](int a, int b){return std::abs(a) < std::abs(b);});
std::cout << "(pairInt.first, pairInt.second): (" << pairInt.first << ", " << pairInt.second << ")" << std::endl;
std::cout << "(pairStr.first, pairStr.second): (" << pairStr.first << ", " << pairStr.second << ")" << std::endl;
std::cout << "(pairSeq.first, pairSeq.second): (" << pairSeq.first << ", " << pairSeq.second << ")" << std::endl;
std::cout << "(pairAbs.first, pairAbs.second): (" << pairAbs.first << ", " << pairAbs.second << ")" << std::endl;
std::cout << std::endl;
}
# std::move
<utility>์ ์ ์๋ std::move๋ ๋ฆฌ์์ค๋ฅผ ์ด๋ํ ์ ์๊ฒ ํด์ฃผ๋ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ด๋ค. std::move๋ฅผ ์ฌ์ฉํ๋ฉด ์์ค(arg)๋ฅผ ์ฐ์ธก๊ฐ ์ฐธ์กฐ๋ก ๋ณํํ๋ค.
std::move์ ์ฐ์ธก๊ฐ ์ฐธ์กฐ์ ๋ํด์๋ C++๊ธฐ์ด ์๋ฆฌ์ฆ์์ ๋ค๋ฃฐ ์์ ์ด๋ค. ์์ธํ ์ฌํญ์ ๋ชจ๋์์ฝ๋๋ฅผ ์ฐธ์กฐํ์.
# std::forward
std::forward๋ ์ฃผ์ด์ง ์ธ์๋ฅผ ๊ทธ๋๋ก ์ ๋ฌํ๋ ํจ์ ํ ํ๋ฆฟ์ ์์ฑํ ์ ์๋ค. std::forward๋ ํฉํ ๋ฆฌ ํจ์๋ ์์ฑ์๋ฅผ ๋ง๋๋ ๋ฐ ์ฃผ๋ก ํ์ฉํ๋ค.
#include <initializer_list>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
struct MyData{
MyData(){};
MyData(int, double, char){};
};
template <typename T, typename ... Args>
T createT(Args&&...args){
return T(std::forward<Args>(args)...);
}
int main(){
int a= createT<int>();
int b= createT<int>(1);
std::string s= createT<std::string>("Only for testing purpose.");
MyData myData= createT<MyData>();
MyData myData2= createT<MyData>(1, 3.19, 'a');
typedef std::vector<int> IntVec;
IntVec intVec= createT<IntVec>(std::initializer_list<int>({1, 2, 3, 4, 5}));
}
ํจ์ ํ ํ๋ฆฟ์ธ createT๋ ์ธ์๋ฅผ ๋ณดํธ ์ฐธ์กฐ ํ์์ธ 'Arg&&...args'๋ก ๋ฐ์์ผ ํ๋ค. ๋ณดํธ ์ฐธ์กฐ๋ ํ์ ์ถ๋ก ์์ ์ฐ์ธก๊ฐ ์ฐธ์กฐ์ธ ๊ฒ์ ๋งํ๋ฉฐ ์ ๋ฌ ์ฐธ์กฐ๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค. std::forward์ ๊ฐ๋ณ ์ธ์ ํ ํ๋ฆฟ์ ์กฐํฉํ๋ฉด ์๋ฒฝํ ์ ๋ค๋ฆญ ํจ์๋ฅผ ๋ง๋ค ์ ์๋ค.
# std::swap
๋ ์ค๋ธ์ ํธ๋ฅผ ๋ง๋ฐ๊พธ๋ ์์ ์ std::swap์ ํตํด ์ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ค. ๋ด๋ถ์ ์ผ๋ก๋ std::move๋ฅผ ํ์ฉํ๊ณ ์๋ค.
#include <algorithm>
#include <iostream>
#include <vector>
template <typename T>
void swap(T& a, T& b){
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
struct MyData{
std::vector<int> myData;
MyData():myData({1, 2, 3, 4, 5}){}
// copy semantic
MyData(const MyData& m):myData(m.myData){
std::cout << "copy constructor" << std::endl;
}
MyData& operator=(const MyData& m){
myData= m.myData;
std::cout << "copy assignment operator" << std::endl;
return *this;
}
};
int main(){
std::cout << std::endl;
MyData a, b;
swap(a, b);
std::cout << std::endl;
};
cppreference์ ์์ ๋ฅผ ๋ณด์.
#include <algorithm>
#include <iostream>
namespace Ns
{
class A
{
int id {};
friend void swap(A& lhs, A& rhs)
{
std::cout << "swap(" << lhs << ", " << rhs << ")\n";
std::swap(lhs.id, rhs.id);
}
friend std::ostream& operator<<(std::ostream& os, A const& a)
{
return os << "A::id=" << a.id;
}
public:
A(int i) : id {i} {}
A(A const&) = delete;
A& operator = (A const&) = delete;
};
}
int main()
{
int a = 5, b = 3;
std::cout << a << ' ' << b << '\n';
std::swap(a, b);
std::cout << a << ' ' << b << '\n';
Ns::A p {6}, q {9};
std::cout << p << ' ' << q << '\n';
// std::swap(p, q); // error, type requirements are not satisfied
swap(p, q); // OK, ADL finds the appropriate friend `swap`
std::cout << p << ' ' << q << '\n';
}
// Output
5 3
3 5
A::id=6 A::id=9
swap(A::id=6, A::id=9)
A::id=9 A::id=6
'C++ ์์ฉ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[STL] std::tuple, std::make_tuple, std::tie, std::ignore (0) | 2023.08.04 |
---|---|
[STL][functional] std::bind, std::function (0) | 2023.06.08 |
vcpkg๋ฅผ ์ฐ์ (0) | 2023.03.19 |
std::thread์ std::async (0) | 2023.01.14 |
[std] iterator๋ณด๋จ const_iterator ! (0) | 2023.01.14 |
๋๊ธ