**๋ฅผ ์ถ๊ฐํด์ค์ผ ํจ
</aside>
- ํจํด ๋งค์นญํ๋ ค๋ฉด struct์ ๋ง๋ค์ด์ ํด์ผํจ
- call operator overriding
๊ทธ๋ค์ instance๋ฅผ ๋ง๋ค์ด์ visit ํจ์์ ๋ฃ์ผ๋ฉด right ํจํด์ด ๋ง๋ ๊ฑฐ๋ฅผ ์ฐพ์์ค์ ํด๋น ํจ์๋ฅผ ๋ถ๋ฌ์ค
```cpp
using myType = std::variant<int, float, std::string>;
struct MyCase { // ํ๋ณํ์ด ๋ง๋
ํ ๋ง๋๊ฒ ์์ผ๋ฉด ์๋จ string์ด๋ฉด string ์์ด์ผํจ. strind ์ int ์์ด๋ ๋จ
void operator()(int i) const {
std::cout << "int " << i << std::endl;
}
void operator()(float i) const {
std::cout << "float " << i << std::endl;
}
void operator()(const std::string& i) const {
std::cout << "string " << i << std::endl;
}
};
int main(void) {
myType v1{"42"};
std::visit(MyCase(), v1);
// ์ ์ฝ๋์ ๊ฐ์ ์๋ฏธ
// auto a = MyCase();
// a(42);
// a(42.2f);
}
```
โintOrFloatOrStr์ด string variant์ด๊ธฐ์ ์ธ๋ฒ์งธ ํจ์๊ฐ ํธ์ถ๋จ
- ๋ง์ฝ์ MyCase์์ ์ธ๋ฒ์งธ ํจ์๋ฅผ ๊น๋จน๊ณ ๊ตฌํ์ํ๋ฉด ์ปดํ์ผํ๊ฒ ๋๋ฉด ์๋ฌ๊ฐ ๋จ
- ml์์์ ์๋ฌ์ ๋น์ท, ๋ฐ๋ผ์ ์ผ์ด์ค๋ฅผ ์๊น๋จน๊ฒ ํด์ค
cf. primitive type์ด ์๋๋ผ๋ฉด(class, struct)๋ผ๋ฉด &๋ฅผ ๋ถ์ฌ์ reference๋ฅผ ์ฌ์ฉ, ์๋ถ์ด๋ฉด copy๊ฐ ๋๋ฌด ๋ง์ด ์ผ์ด๋๊ธฐ ๋๋ฌธ!! ๋ํ const๋ฅผ ๋ถ์ด๋ฉด not change state๋ฅผ ๋ช
์ํ ์ ์์!
### Multsign function Example
๊ณฑํด์ ๋ถํธ๋ฅผ ๋ฆฌํดํ๋ ํจ์
```cpp
struct P {};
struct N {};
struct Z {};
variant<P,N,Z> multsign(int x, int y) {
auto sign = [](int v) {
if (v>0) { return variant<P,N,Z>(P{});
} else if (v<0) { return variant<P,N,Z>(N{});
} else { return variant<P,N,Z>(Z{});}
};
struct MyCase {
variant<P,N,Z> operator()(const P& v1, const P& v2) { return variant<P,N,Z>(P{});}
variant<P,N,Z> operator()(const P& v1, const N& v2) { return variant<P,N,Z>(N{});}
variant<P,N,Z> operator()(const P& v1, const Z& v2) { return variant<P,N,Z>(Z{});}
variant<P,N,Z> operator()(const N& v1, const P& v2) { return variant<P,N,Z>(N{});}
variant<P,N,Z> operator()(const N& v1, const N& v2) { return variant<P,N,Z>(P{});}
variant<P,N,Z> operator()(const N& v1, const Z& v2) { return variant<P,N,Z>(Z{});}
variant<P,N,Z> operator()(const Z& v1, const P& v2) { return variant<P,N,Z>(Z{});}
variant<P,N,Z> operator()(const Z& v1, const N& v2) { return variant<P,N,Z>(Z{});}
variant<P,N,Z> operator()(const Z& v1, const Z& v2) { return variant<P,N,Z>(Z{});}
};
return std::visit(MyCase{}, sign(x), sign(y));
}
```
- nest function์ ์ ์ธ: ๊ฐ ์ ์์ ๋ถํธ๋ฅผ ํ๋จํด์ variant๋ฅผ ์์ฑํ๋ ํจ์
- ์๊น๋ visit์์๋ ํ๊ฐ์ arugment๋ฅผ ๋ณด๋๋๋ฐ ์ง๊ธ์ ๋๊ฐ์ arugment๋ฅผ ๋ณด๋ โ ๊ฐ๊ฐ์ ๋๊ฐ์ ๋ณ์์ ๋ํด์ override๋ฅผ ํด์ค์ผ ํจ
- ์๊น๋ 3๊ฐ์ ํจ์๋ฅผ ์ค๋ฒ๋ก๋ฉ, ์ง๊ธ์ 3* 3 = 9๊ฐ์ง์ ๊ฒฝ์ฐ์ ์๊ฐ ์๊ธฐ์ 9๊ฐ์ ํจ์๋ฅผ ์ค๋ฒ๋ก๋ฉ
- ํ๋์ ๊ฒฝ์ฐ์ ์๋ผ๋ ์์ผ๋ฉด ์๋ฌ๊ฐ ๋จ
cf. primitive type์ด ์๋๊ธฐ์ const, &์ ๋ถ์: &์ ์ต์ ํ๋ฅผ ์ํด์ const๋ ์
๋ฐ์ดํธ ์ํจ์ ๋ช
์ํ๊ธฐ ์ํด ์ฌ์ฉ
๋๊ฐ์ arugment ์ค์ ํ๋๋ผ๋ 0์ด๋ฉด z์ด ๋์ค๊ฒ ๋จ
```cpp
struct P {std::string str() {return "p";}} //str()๋ก ๋ฌถ์ด์ ์๋ ํ๋ ค๊ณ ํ๋๋ฐ variantํ์
์ด ์ค๊ธฐ์ ์ด์ฐ๋์๋ ๋ถ๊ธฐ๋ก ํด์ผ ํจ
struct N {std::string str() {return "N";}}
struct Z {std::string str() {return "Z";}}
auto res = multsign(1,-1); // N์ด ๋์ด
if (std::holds_alternative(res)) {
cout<<"P"<<endl;
} else if(std::holds_alternative(res)) {
cout<<"N"<<endl;
} else {
cout<<"Z"<<endl;
}
```
cf. visit์์ exhaustiveํ์ง ์ปดํ์ผํ์์ ์ฒดํฌํ๋ ํธ
cf. MyCase๋ฅผ ์ต์ ํํ๋ค๋ฉด auto๋ก ๋ฐ์์ ๋๋จธ์ง๋ฅผ ๋ค ๋ฌถ์ด์ ํ ์๋ ์์!
**โtemplate์ ์ฌ์ฉํด์ ์ข ๋ ์ฝ๊ฒ ๋ฐ๊ฟ๋ณด์**
```cpp
//Ts๋ค์ ์์๋ฐ๋ template strcture
template struct overload : Ts... { using Ts::operator()...; };
// guide, ์๋๋ template ์ด๋๊น ํ์
๋ช
์๋ฅผ ํ๋ฉด์ ์์ฑ์๋ฅผ ํธ์ถํด์ผํ๋๋ฐ ๊ทธ๊ฑธ ํธํ๊ฒ ํ๊ธฐ ์ํ ๊ผผ์ !!
template overload(Ts...) -> overload;
```
template์ ์ฐ๋ฉด MyCase struct์ ์๋์ฒ๋ผ overload ๋๋คํจ์๋ก ๋ฐ๊ฟ ์ ์์!!
- ์ฒซ๋ฒ์งธ ์ค
- ์ฌ๋ฌ ์ ํ์ ์์๋ฐ๋ template structure์ ์ ์ธ
- using๋ฌธ์ Ts์์ ()๊ฐ ์๋๋ฐ namespace๋ฅผ ์ฐ๊ณ ์ถ์ง ์์์ ์ ์ ์ฝ๋ โ ๋ชจ๋ ()์ฐ์ฐ์ ํจ์๋ฅผ overload ํด๋์ค๋ก ๊ฐ์ ธ์ค๋ ํจ๊ณผ
- ๋๋ฒ์งธ๋ guide, ์ปดํ์ผ๋ฌ์๊ฒ ์๋ ค์ฃผ๋ ๊ฐ์ด๋
- overload ๊ฐ์ constructor๊ฐ ์๋ค๋ฉด ์์ ํ
ํ๋ฆฟ์ผ๋ก ํ๋ผ๊ณ ์๋ ค์ฃผ๋ ๊ฒ
- ์ฆ, overload ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์ ์ํ๊ณ ์์ฑ์์ ํด๋น ์ธ์๋ฅผ ์ ๋ฌ
- ์ฝ๋์์ overload ๊ตฌ์กฐ์ฒด์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋, Ts์ ์ฌ๋ฌ ๊ฐ์ ํจ์ ํฌ์ธํฐ๋ฅผ ์ ๋ฌํ๋ฉด, ํด๋น ํจ์๋ค์ ์์ํ overload ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ์์ฑ๋ overload ๊ฐ์ฒด๋ std::visit ํจ์ ํธ์ถ์ ์ฌ์ฉ๋์ด std::variant์ ์ ์ฅ๋ ๊ฐ์ ์ ํ์ ํ๋ณํ๊ณ ํด๋น ์์
์ ์ํํฉ๋๋ค.
```cpp
auto res = std::visit(overload{
[](const P& v1, const P& v2) { return variant<P,N,Z>(P{});},
[](N& v1, N& v2) { return variant<P,N,Z>(P{});},
[](P& v1, N& v2) { return variant<P,N,Z>(N{});},
[](N& v1, P& v2) { return variant<P,N,Z>(N{});},
[](auto, auto) { return variant<P,N,Z>(Z{});}, //base case๋ฅผ ์๋ฏธ, generic lamda๋ผ๊ณ ๋ถ๋ฆ(c++14)
//๋ง์ฝ์ sign x, y๊ฐ ์์ 4๊ฐ๊ฐ ์๋๋ฉด ๋ถ๋ ค์ง
},sign(x), sign(y));
```
โ commma separate ๋๊ณ overload๋ struct์ ๊ฐ์ง๊ธฐ์ ์ด์ ์ฝ๋์ ๋์ผํ ํจ๊ณผ๋ฅผ ๊ฐ์ง
- templete class ์ ์ธ์ด๊ณ ๋ฐ์ ๊ฐ์ด๋์ธ๋ฐ templete definition ์์ ์๋๊ฑฐ, overload๋ผ๋ ํ
ํ๋ฆฟ ํด๋์ค ๊ตฌ์กฐ์ฒด๋ก๋ถํฐ ์ ๋๋คํจ์๋ค์ ํด๋นํ๋ structure์ ๋ง๋ค์ด์ ๊ทธ๋ ๊ฒ ๋ง๋ค์ด์ง ๊ตฌ์กฐ์ฒด๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ํด์ ์ค์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ณ visit ํจ์๊ฐ operator๋ฅผ ์ ๊ทผํ ๋ ์ด๋ฆ์์ด ์ ๊ทผํ๊ธฐ์ using์ด ์๋ ๊ฒ
template class๋ ์ดํดํ ํ์๋ ์์ง๋ง ์ธ ์๋ ์์ด์ผํจ
### expression tree
ml์์ ํ ๊ฑฐ๋ฅผ c++์์ ํด๋ณด์
- expression tree๋ recursive datatype์ด ๋ฝ์ธํธ!
![แแ
ณแแ
ณแ
แ
ตแซแแ
ฃแบ 2023-04-14 แแ
ฉแแ
ฎ 10.33.17.png](Lecture03%20cpp-updated%2075191ea85b41457498dc4778946c01d6/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-04-14_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_10.33.17.png)
๋์๋๋? no! ์์ง expr์ ์ ์ธ์ํ์ผ๋๊น!
![แแ
ณแแ
ณแ
แ
ตแซแแ
ฃแบ 2023-04-14 แแ
ฉแแ
ฎ 10.33.33.png](Lecture03%20cpp-updated%2075191ea85b41457498dc4778946c01d6/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-04-14_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_10.33.33.png)
struct์ ์ธํ๊ธฐ์ ์ ์์ variant์ ์ด๋ค๋ฉด???
์๊ฐ ์ผ๋ง๋ ์คํ์ด์ค๋ฅผ ์ฐ๋์ง๋ชจ๋ฅด๊ธฐ์ ์ธ ์ ์์ ใ
โ ํฌ์ธํฐ๋ก ํด๋ณด์: ๋์ง๋ง ์ฐ๋ฆฌ๋ ml์์ ํ๋ ๊ฑฐ์ฒ๋ผ ํ๊ณ ์ถ์!( new ์์ด)
![แแ
ณแแ
ณแ
แ
ตแซแแ
ฃแบ 2023-04-14 แแ
ฉแแ
ฎ 10.36.29.png](Lecture03%20cpp-updated%2075191ea85b41457498dc4778946c01d6/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-04-14_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_10.36.29.png)
cf.expr ๋์ variant๋ก ์ ์ผ๋ฉด ๋์ง ์๋? ์๋์ง ์ ์ธ์ ์ํ์ผ๋๊น ๋์ ํฌ์ธํฐ๋ก ํ๋ค๋ฉด ๊ฐ๋ฅ~
### Expresstion tree in c++
box๋ Negate, add, mult๋ฅผ ๋ฐ์์ expr๋ก ๋ฐ๊ฟ์ฃผ๊ธฐ ์ํด box๋ก wrappingํจ
```cpp
template // T๋ negate, add, mult๊ฐ ๋ ๊ฒ
class box {
std::unique_ptr _impl;
public:
box (T &&obj): _impl(new T(std::move(obj))) {} //์ ๊น ์กด์ฌํ๋ ์ ๋ฅผ deep copyํ์ง ๋ง๊ณ shallow copyํด๋ผ๋ ์๋ฏธ
box (const T &obj):_impl (new T(obj)) {}
// copy constructor
box (const box &other):box(*other._impl) {}
box &operator=(const box &other) {
*_impl = *other._impl;
return *this;
}
// move constructor
box (box &&other) : box (std:: move (*other._impl)) {}
box &operator= (box &&other) {
*_impl = std::move(*other._impl);
return *this;
}
~box() = default;
T &operator*() { return *_impl; } // * operator, ์ค์ ๊ฐ์ฒด์ ๋ ํผ๋ฐ์ค๋ฅผ ๋๋ ค์ค
const T &operator* () const { return *_impl; } // * operator
T *operator->() { return _impl.get () ;} // -> operator
const T *operator->() const { return _impl.get () ; } //-> operator,ํฌ์ธํฐ๋ฅผ ๋๋ ค์ค์ attribute๋ฅผ ์ ๊ทผ
};
```
![แแ
ณแแ
ณแ
แ
ตแซแแ
ฃแบ 2023-04-14 แแ
ฉแแ
ฎ 10.44.32.png](Lecture03%20cpp-updated%2075191ea85b41457498dc4778946c01d6/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-04-14_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_10.44.32.png)
![แแ
ณแแ
ณแ
แ
ตแซแแ
ฃแบ 2023-04-14 แแ
ฉแแ
ฎ 10.41.53.png](Lecture03%20cpp-updated%2075191ea85b41457498dc4778946c01d6/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-04-14_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_10.41.53.png)
- negation ์ค๋ธ์ ํธ๋ฅผ ๋ง๋ค์ด์ mult ์์ฑ์๋ฅผ ๋ฐ์ผ๋ ค๊ณ ํ๋๋ฐ ์์ฑ์ expr์ด์๋!! ๊ทธ๋์ ์ปดํ์ผ๋ฌ๊ฐ negation โ expr๋ก ๋ฐ๊ฟ์ค ์ด๋ฅผ ์ํด box๋ก wrappingํด์ expr๋ก ๋ฐ๊ฟ์ค
- ๋ฐ์ค๊ฐ ํ๋ ์ผ์ด ๋ญ๊น? stack์ ํ ๋น๋ ๋ฒจ๋ฅ(Negate)๋ฅผ ๋ฐ์์ ๋๊ฐ์ ์ค๋ธ์ ํธ๋ฅผ heap allocaitonํด์ unique ptr์ด reference countํด์ ๋นํ ๋นํด์ฃผ๋ ๊ฑฐ๊ณ ๋ช๊ฐ์ง ์ฐ์ฐ์๊ฐ ์์ด์ ํธํ๊ฒ ํด์ค
cf.๋ชฐ๋ผ๋๋จ! &&๊ฐ ์๋๊ฒ rvalue reference๋ผ๋ ๊ฒ: ๊ณง ์ฌ๋ผ์ง object์ ๋ ํผ๋ฐ์ค๋ฅผ ์๋ฏธ, ์ด๊ฒ ์ข ์ด๋ ค์. ์ด ๊ฐ๋
์์ฒด๊ฐ ํ๋ก๊ทธ๋๋จธ๋ฅผ ์ํ ๊ฒ ์๋๋ผ ์ปดํ์ผ๋ฌ ์ต์ ํ๋ฅผ ์ํด์ ๋ง๋ค์ด์ง ๊ฐ๋
์ด๋ผ์ ์ด๋ ค์. negate๊ฐ ํ์ ๋ง๋ค์ด์ง์ ๋ง์ mult ์์ฑ์๋ก ๋ค์ด๊ฐ๊ฑฐ์. ๊ทธ๋๊น ์ ๊น๋ง ์กด์ฌํ๋ ์ค๋ธ์ ํธ๋ผ๊ณ ๋ณผ ์ ์๋๋ฐ ๊ทธ๋ฐ ๊ฒฝ์ฐ์ ๊ฑ๋ฅผ ๋ฐ์์ std::move๊ฐ heap์ negate๋ฅผ ๋ง๋๋๋ฐ copy ์์ฑ์ ๋ถ๋ฅด์ง๋ง๊ณ ์์ ์ค๋ธ์ ํธ๋ก ํฌ์ธํ
ํ๋ ์ ๋ค์ ๊ทธ๋ฅ ํฌ์ธํ
ํด๋ผ. deep copyํ์ง ๋ง๊ณ shallow copyํด๋ผ๋ ์๋ฏธ! โ ๊ทธ๋ฌ๋ฉด ํ์์์ ๋ ์ค์ฝฅ์ด ๋๋๋ฉด ๊ฑ๊ฐ ์์ด์ง๋๊น~rvalue reference ์์ฑ์๊ฐ ๋ถ๋ฅด๋๋ก ๊ฐ์ ํ๋๊ฒ moveํจ์
cf2.mult ์ค๋ธ์ ํธ๋ฅผ ๋ค์ add์ ์ฎ๊ธธ ๋ ์ฌ์ฉ, expr์์์ ํฌ์ธํฐ๋ก box๋ฅผ ๊ฐ๊ณ ์๋๋ฐ ์ด๋ ๋ค ์นดํผํ์ง ์๊ณ ๋ฌด๋ธํ๋ค~ : ๊ฒฐ๋ก ์ ์ต์ ํํ๋ ๊ฑฐ๋ค~ ๋ชฐ๋ผ๋ ๋จ>ใ
<
- ์ด์ ml๊ณผ ๋น์ทํ Expression tree๋ฅผ ๋ง๋ค์๊ณ evalํจ์๋ฅผ ๋ง๋ค์ด๋ณด์~
### eval function
*box&์ด์ง Add&๊ฐ ์๋*
```cpp
template struct overload : Ts... { using Ts::operator()...; }; //template strcture
template overload(Ts...) -> overload; // guide, ์๋๋ template ์ด๋๊น ํ์
๋ช
์๋ฅผ ํ๋ฉด์ ์์ฑ์๋ฅผ ํธ์ถํด์ผํ๋๋ฐ ๊ทธ๊ฑธ ํธํ๊ฒ ํ๊ธฐ ์ํ ๊ผผ์ !!
int eval(Expr e) {
return std::visit(overload{
[](const Constant& c) {return c.val;},
[](box& e) {return -(eval(e->e));},
[](box& e) {return eval(e->e1) + eval(e->e2);},
[](box& e) {return eval(e->e1) * eval(e->e2);}
},e);
}
```
const๋ฅผ ๋๋ค ํจ์ ์์ ์ ๋๊ฒ ์ฌ์ค ๋ ์ข์
### max_const
```cpp
int max_const(Expr e) {
return std::visit(overload {
[](Constant& c) {return c.val;},
[](box& c) {return max_const(c->e);},
[](box& c) {return **std::max**(max_const(c->e1), max_const(c->e2));},
[](box& c) {return std::max(max_const(c->e1), max_const(c->e2));}
}, e);
}
```
### count_adds
```cpp
int count_adds(Expr e) {
return std::visit(overload {
[](Constant& c) {return 0;},
[](box& c) {return count_adds(c->e);},
[](box& c) {return 1 + count_adds(c->e1) + count_adds(c->e2);},
[](box& c) {return count_adds(c->e1) * count_adds(c->e2);},
}, e);
}
```
### expr in oop
- unique ptr์ด๋ box class๋ฅผ ์ฌ์ฉํด์ผ ํจ
any ํจ์์ ๋ํ ์ฝ๋๋ฅผ ์ฌ๋ฆดํ
๋ ํจ ๋ด๋ผ