#include <iostream>
#include <vector>
#include <list>
using namespace std;
class Test
{
public:
template<typename T> static void f() {}
template<typename T> class Complex {};
};
template<typename T> void foo(T a) // T: Test
{
// OK
Test::f<int>();
// Error(임의 타입 T에서 < 연산자의 정의를 알 수 없음)
//T::f<int>();
// OK(임의 타입 T로 사용할 경우 ::template 키워드를 사용해야한다.)
T::template f<int>();
// OK
Test::Complex<int> c1;
// Error(::Complex가 값인지 타입인지 알수 없음)
//T::Complex<int> c2;
// Error(임의 타입 T에서 < 연산자 정의를 알 수 없음)
//typename T::Complex<int> c3;
// OK(임의 타입 T로 사용할 경우 ::template 키워드를 사용해야한다.)
typename T::template Complex<int> c4;
}
int main()
{
Test t;
foo<Test>(t);
}
#include <iostream>
#include <vector>
#include <list>
using namespace std;
//컨테이너의 데이터 타입
template<typename T>
void print_first_element(T& v)
{
// 1.값의 데이터 타입이 필요한 경우
typename T::value_type n = v.front();
// 2.값의 데이터 타입 대신 auto사용 가능
auto n = v.front();
cout << n << endl;
}
int main()
{
list<double> v = { 1,2,3 };
print_first_element(v);
}
C++ 17에서 클래스 템플릿 타입 추론(Class Template Type Deduction)에서 value_type 사용 예
#include <iostream>
#include <vector>
#include <list>
using namespace std;
template<typename T>
class Vector
{
T* buff;
int size;
public:
Vector(int sz, T value) {}
template<typename C> Vector(C c) {}
};
// C++ 17의 클래스 사용자 정의 타입 추론을 정의할때 아래와 같이 값의 타입이 필요한 경우 auto 사용이 불가
template<typename C>
Vector(C c)->Vector<typename C::value_type>;
int main()
{
Vector v(10, 3);
// Vector에 list Container 인자로 넣을 경우, Container 내부 값의 타입 추론이 필요하다.
list s = { 1,2,3 };
Vector v2(s);
}
#include <iostream>
using namespace std;
class Test
{
public:
enum { value1 = 1 };
static int value2;
typedef int INT;
using SHORT = short;
class innerClass {};
using DWORD = int;
};
int Test::value2;
template<typename T>
int foo(T t)
{
// 타입으로 해석
//typename T::DWORD* p;
// 값으로 해석
//T::DWORD* p;
return 0;
}
int main()
{
Test t;
foo(t);
}
template<typename T> class Complex
{
T re, im;
public:
void foo(Complex c) // 멤버 함수에서는 OK(Complex<T> 동급으로 취급)
{
}
};
void foo(Complex c) // 일반 함수에서는 Error
{
}
void foo(Complex c)
{
Complex c1; // Error
Complex<int> c2; // OK
}
템플릿 관련 표기법
디폴트 값 표기
int a = 0;
T a = T(); // C++ 98/03
T a = {}; // C++11
멤버 함수를 외부에 표기
static memeber data 외부 표기
클래스 템플릿의 멤버 함수 템플릿 표기
template<typename T> class Complex
{
T re, im;
public:
// 디폴트 값 표기
Complex(T a = {}, T b = {}) : re(a), im(b) {}
T getReal() const;
static int cnt;
template<typename U> T func(const U& c);
};
// 클래스 템플릿의 멤버 함수 템플릿 구현
template<typename T> template<typename U>
T Complex<T>::func(const U& c)
{
}
// static 멤버 데이터 외부 구현
template<typename T>
int Complex<T>::cnt = 0;
// 멤버 함수 외부 구현
template<typename T>
T Complex<T>::getReal() const
{
return re;
}
int main()
{
Complex<int> c2;
}
Info.plist에 메시지를 추가 했으면 계정에 권한 요청을 위해서 로컬 코드를 업데이트 해야합니다.
권한 요청
Status: Authorized
IDFA를 ASIdentifierManager에서 조회
Status: Denied
사용자 설정 페이지로 이동
Status: Not Determined
사용자에게 권한을 요청하고 다이얼로그를 표시
import AdSupport
import AppTrackingTransparency
func requestPermission() {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
// Tracking authorization dialog was shown
// and we are authorized
print("Authorized")
// Now that we are authorized we can get the IDFA
print(ASIdentifierManager.shared().advertisingIdentifier)
case .denied:
// Tracking authorization dialog was
// shown and permission is denied
print("Denied")
case .notDetermined:
// Tracking authorization dialog has not been shown
print("Not Determined")
case .restricted:
print("Restricted")
@unknown default:
print("Unknown")
}
}
}
어떻게 권한 요청을 하는지 애플 다이얼로그 예제입니다.
만약 사용자가 권한을 허용하지 않는다면 UUID값은 모두 0으로 표기되어 반환됩니다.
파란색 박스가 개발자가 앱속 Info.plist에 추가 작업한 메시지가 표시되는 영역입니다.