수색…


비고

유형 특성은 컴파일시 서로 다른 유형의 특성을 비교하고 테스트하는 데 사용되는 템플리트 구조입니다. 컴파일 타임에 조건부 논리를 제공하여 특정 방식으로 코드의 기능을 제한하거나 확장 할 수 있습니다. 형질 특성 라이브러리는 다양한 기능을 제공하는 c++11 표준으로 도입되었습니다. 자신 만의 형질 비교 템플릿을 만들 수도 있습니다.

표준 형질

C ++ 11

type_traits 헤더는 컴파일 타임에 유형의 특성을 변환하고 점검 할 수있는 템플릿 클래스 및 헬퍼 세트를 포함합니다.

이러한 특성은 일반적으로 템플릿에서 사용자 오류를 확인하고 일반 프로그래밍을 지원하며 최적화를 허용하는 데 사용됩니다.


대부분의 형질 특성은 유형이 몇 가지 기준을 충족하는지 확인하는 데 사용됩니다. 이들은 다음과 같은 형식을 가지고 있습니다 :

template <class T> struct is_foo;

템플리트 클래스가 foo 를 만족하는 유형으로 인스턴스화 된 경우 is_foo<T>std::integral_constant<bool,true> (일명 std::true_type )에서 상속받습니다. 그렇지 않으면 std::integral_constant<bool,false> (일명 std::false_type ). 이것은 특성에 다음 구성원을 제공합니다.

상수

static constexpr bool value

true 경우 T 기준의 충족 foo , false , 그렇지 않으면

기능들

operator bool

value 반환 value

C ++ 14

bool operator()

value 반환 value

유형

이름 정의
value_type bool
type std::integral_constant<bool,value>

이 특성은 static_assert 또는 std::enable_if 와 같은 구문에서 사용될 수 있습니다. std::is_pointer :

template <typename T>
void i_require_a_pointer (T t) {
    static_assert(std::is_pointer<T>::value, "T must be a pointer type");
}

//Overload for when T is not a pointer type
template <typename T>
typename std::enable_if<!std::is_pointer<T>::value>::type
does_something_special_with_pointer (T t) {
    //Do something boring
}

//Overload for when T is a pointer type
template <typename T>
typename std::enable_if<std::is_pointer<T>::value>::type 
does_something_special_with_pointer (T t) {
    //Do something special
}

또한 std::add_pointerstd::underlying_type 과 같은 형식을 변환하는 다양한 특성이 있습니다. 이러한 특성은 일반적으로 변형 된 형식을 포함하는 단일 type 멤버 형식을 노출합니다. 예를 들어 std::add_pointer<int>::typeint* 입니다.

std :: is_same과 타입 관계

C ++ 11

std::is_same<T, T> 형식 관계는 두 가지 형식을 비교하는 데 사용됩니다. 부울로 평가되며 유형이 동일하면 true이고 그렇지 않은 경우 false입니다.

// Prints true on most x86 and x86_64 compilers.
std::cout << std::is_same<int, int32_t>::value << "\n";
// Prints false on all compilers.
std::cout << std::is_same<float, int>::value << "\n";
// Prints false on all compilers.
std::cout  << std::is_same<unsigned int, int>::value << "\n";

std::is_same 형식 관계는 typedef와 관계없이 작동합니다. 이것은 int == int32_t 비교할 때 첫 번째 예제에서 실제로 나타 int == int32_t 그러나 이것은 완전히 명확하지 않습니다.

// Prints true on all compilers.
typedef int MyType
std::cout << std::is_same<int, MyType>::value <<  "\n";

템플리트 화 된 클래스 또는 함수를 부적절하게 사용할 때 경고하기 위해 std::is_same 을 사용합니다.

정적 어설 션과 결합하면 std::is_same 템플릿이 템플릿 클래스 및 함수의 적절한 사용을 시행하는 데 유용한 도구가 될 수 있습니다.

예를 들어 int 에서 입력을 허용하고 두 개의 구조체 중에서 선택할 수있는 함수.

#include <type_traits>
struct foo {
  int member;
  // Other variables
};

struct bar {
  char member;
};

template<typename T>
int AddStructMember(T var1, int var2) {
  // If type T != foo || T != bar then show error message.
  static_assert(std::is_same<T, foo>::value || 
    std::is_same<T, bar>::value,
    "This function does not support the specified type.");
  return var1.member + var2;
}

기본형 형질

C ++ 11

보다 일반적인 유형을 비교하는 여러 유형의 특성이 있습니다.

적분 :

int , char , long , unsigned int 등의 모든 정수 유형에 대해 true로 평가됩니다.

std::cout << std::is_integral<int>::value << "\n"; // Prints true.
std::cout << std::is_integral<char>::value << "\n"; // Prints true.
std::cout << std::is_integral<float>::value << "\n"; // Prints false.

부동 소수점 :

모든 부동 소수점 유형에 대해 true로 평가됩니다. float , double , long double

std::cout << std::is_floating_point<float>::value << "\n"; // Prints true.
std::cout << std::is_floating_point<double>::value << "\n"; // Prints true.
std::cout << std::is_floating_point<char>::value << "\n"; // Prints false.

열거 형 :

enum class 포함한 모든 열거 형에 대해 true로 평가됩니다.

enum fruit {apple, pair, banana};
enum class vegetable {carrot, spinach, leek};
std::cout << std::is_enum<fruit>::value << "\n"; // Prints true.
std::cout << std::is_enum<vegetable>::value << "\n"; // Prints true.
std::cout << std::is_enum<int>::value << "\n"; // Prints false.

포인터인가?

모든 포인터에 대해 true로 평가합니다.

std::cout << std::is_pointer<int *>::value << "\n"; // Prints true.
typedef int* MyPTR;
std::cout << std::is_pointer<MyPTR>::value << "\n"; // Prints true.
std::cout << std::is_pointer<int>::value << "\n"; // Prints false.

클래스입니다 :

enum class 제외하고 모든 클래스와 구조체에 대해 true로 평가됩니다.

struct FOO {int x, y;};
class BAR {
 public:
  int x, y;
};
enum class fruit {apple, pair, banana};
std::cout << std::is_class<FOO>::value << "\n"; // Prints true.
std::cout << std::is_class<BAR>::value << "\n"; // Prints true.
std::cout << std::is_class<fruit>::value << "\n"; // Prints false.
std::cout << std::is_class<int>::value << "\n"; // Prints false.

유형 특성

C ++ 11

유형 특성은 다른 변수에 배치 할 수있는 수정자를 비교합니다. 이러한 형질 특성의 유용성은 항상 명확하지 않습니다.

참고 : 아래의 예는 최적화되지 않은 컴파일러에서만 개선점을 제공합니다. 복잡한 예가 아니라 단순한 개념 증명입니다.

Fast는 4로 나눕니다.

template<typename T>
inline T FastDivideByFour(cont T &var) {
  // Will give an error if the inputted type is not an unsigned integral type.    
  static_assert(std::is_unsigned<T>::value && std::is_integral<T>::value,
    "This function is only designed for unsigned integral types.");
  return (var >> 2);
}

상수 :

type이 일정 할 때 true로 평가됩니다.

std::cout << std::is_const<const int>::value << "\n"; // Prints true.
std::cout << std::is_const<int>::value << "\n"; // Prints false.

휘발성인가 :

유형이 일시적 일 때 true로 평가됩니다.

std::cout << std::is_volatile<static volatile int>::value << "\n"; // Prints true.
std::cout << std::is_const<const int>::value << "\n"; // Prints false.

서명 됨 :

이것은 모든 서명 된 유형에 대해 true로 평가됩니다.

std::cout << std::is_signed<int>::value << "\n"; // Prints true.
std::cout << std::is_signed<float>::value << "\n"; // Prints true.
std::cout << std::is_signed<unsigned int>::value << "\n"; // Prints false.
std::cout << std::is_signed<uint8_t>::value << "\n"; // Prints false.

서명되지 않음 :

모든 부호없는 유형에 대해 true로 평가됩니다.

std::cout << std::is_unsigned<unsigned int>::value << "\n"; // Prints true.
std::cout << std::is_signed<uint8_t>::value << "\n"; // Prints true.
std::cout << std::is_unsigned<int>::value << "\n"; // Prints false.
std::cout << std::is_signed<float>::value << "\n"; // Prints false.


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow