Effective Modern C++

2022. 4. 21. 19:55Programming/JAVA, C++, Go, Rust

    목차
반응형

Uniform Initializer

 

narrowing cast 방지

 

	class DataType {
	public:
		int a;
		string b;
	};
	
	DataType = {1, "2"};

std::vector<std::string> myVec = {“String 1”, “String 2”, “String 3”}

 

MyClass
    {
    public:
        MyClass(initializer_list<double> args)
...
};

MyClass p1 = {1.0, 2.0, 3.0, 4.0};

 

Explicit

implicit type conversion을 막기 위해서 explicit type conversion이 되도록 처리

생성자와 치환 연산자에 explicit keyword 처리

 

int iC1 = c; <- 이런 implicit conversion을 막고

int iC2 = int(c); 명시적 conversion만 허용하고자 할 경우, 

 

class IntWrapper {
...
    explicit operator int() const { return mInt; }
...
};

 

move semantics

	vector<Element> vec;
	vec.push_back(Element(12, "Twelve"));   <- copy 대신 move가 발생
	
	vector<Element> func(...) {
		...
		return vec;		// copy 대신 move 발생
	}

 

const_iterator

기존 iterator의 경우 값 변경이 가능함,

값을 바꾸지 않게 하려면 다음과 같은 방법으로 const_iterator를 사용하면 됨

 

for (auto iter = vec.cbegin(); iter != vec.cend(); ++iter) ...

 

Lambda expression

[capture_block](param_list) mutable exception_list -> return type { body }

 

[]{ ... }();  // 끝에 ()는 Lambda expression을 즉시 동작 시킴

 

auto lf = [](const string& str)->string{ return str + "a"; }

 

capture block

 

  • []  no capture
  • [=] 모든 변수를 값으로서 복제하여 capture
  • [&] 모든 변수를 참조로서 (원본을 수정할 수 있는) capture 
  • [&x] : 변수 x만을 참조로서 capture
  • [x]  : 변수 x만을 값으로서 capture
  • [&, x] : 모든 변수를 default 참조로 capture하되 변수 x에 대해서는 값으로 capture

 

Lambda의 return

		function<int(void)> getLambda(int x) {
			return [=]()->{ return 2*x; };
			or
			return [=]{return 2*x;}
		}

 

bind

함수 호출 시 인자가 bind 되도록 함

 

void func(int num, const string &str);

 

두 번째 param str을 고정하려면 다음과 같이 bind

 

		string str = "abc";
		auto f1 = bind(func, placeholders::_1, str);
		f1(16)

 

인자 순서 변경

		auto f2 = bind(func, placeholders::_2, placeholders::_1);
		f2("test", 32);

 

type deduction

template <typename T>
void f(T& param)

int x = 27;
f(x);           // int&

const int cx = x;
f(cx);          // const int&

const int& rx = x;
f(rx);          // const int

 

template<typename T>
void f(const T& param);

int x = 27;
const int cx = x;
const int& rx = x;

f(x);       // const int&
f(cx);      // const int&
f(rx);      // const int&

 

universal reference type deduction

universal ref.은 template의 T&& 혹은 auto&&

 

R-value ref.으로 초기화 되는 universal ref.는 R-value ref.임

L-value ref.으로 초기화 되는 universal ref.는 L-value ref.임

template<typename T>
void f(T&& param);

int x = 27;
const int cx = x;
const int& rx = x;

f(x);       // int&
f(cx);      // const int&
f(rx);      // const int&
f(27);      // int&&

 

auto type deduction

auto x = 27;
const auto cx = x;
const auto& rx = x;

auto&& uref1 = x;           // int&
auto&& uref2 = cx;          // const int&
auto&& uref3 = 27;          // int&&

auto x = 27;
const auto cx = x;
const auto& rx = x;

auto&& uref1 = x;           // int&
auto&& uref2 = cx;          // const int&
auto&& uref3 = 27;          // int&&

 

decltype

const int i = 0;            // decltype(i) is const int
Widget w;                   // decltype(w) is Widget
if (f(w)) …                 // decltype(f(w)) is bool

 

 

사용 경우

return type이 바뀔 수 있어 auto로 return 해야 하는 경우 사용

 

C++14에서는 decltype 없이 auto return 사용 가능

 

template<typename Container, typename Index> // C++14;
auto authAndAccess(Container& c, Index i)
{
	...
	return c[i]; // return type deduced from c[i]
}

 

 

반응형

'Programming > JAVA, C++, Go, Rust' 카테고리의 다른 글

task-based programming  (0) 2022.04.21
Smart pointers  (0) 2022.04.21
Universal reference  (0) 2022.04.16
make_shared, make_unique의 장점  (0) 2022.04.16
Go 언어 변수 선언  (0) 2022.01.09