source

static_assert를 사용하여 매크로에 전달된 유형을 확인합니다.

manycodes 2023. 11. 2. 21:55
반응형

static_assert를 사용하여 매크로에 전달된 유형을 확인합니다.

불행하게도 제 라이브러리의 원래 버전에서 꽤 미친 C를 사용한 매크로가 몇 개 남아 있습니다.특히, 저는 특정한 종류가 자신에게 전달되기를 기대하는 일련의 매크로를 가지고 있습니다.다음과 같은 작업을 수행할 수 있습니까?

static_assert(decltype(retval) == bool);

어떻게?현명한 대안이 있습니까?

네 매크로가 나쁘다는 것을 알고 있습니다.C++는 C 등이 아닌 것으로 알고 있습니다.

업데이트 0

여기 관련된 코드소스 파일이 있습니다.제안을 환영합니다.원래 질문은 그대로입니다.

@UncleBens 제안을 사용하면 가장 깨끗하다는 것을 알 수 있었습니다.

#include <type_traits>

static_assert(std::is_same<decltype(retval), bool>::value, "retval must be bool");

면책 사항:이것은 나쁜 대답입니다. 훨씬 더 나은 해결책이 분명히 있습니다.예를 들어보자 :)

이미 시행될 수밖에 없지만, 스스로 시행하는 것은 사소한 일입니다.

template <class T1, class T2> struct CheckSameType; //no definition
template <class T> struct CheckSameType<T,T>{}; //

template <class T1, class T2>
AssertHasType(T2)
{
   CheckSameType<T1, T2> tmp; //will result in error if T1 is not T2
}

다음과 같이 사용하려면:

AssertHasType<bool>(retval);

대안(GMan이 제안):

template <class T1, class T2> struct SameType
{
    enum{value = false};
}
template <class T> struct SameType<T,T>
{
    enum{value = true};
}; 

다음과 같이 사용됩니다.

static_assert(SameType<decltype(retval), bool>::value);

필요하신 것 같네요decltype표현은 있지만 유형을 확인하려고 하기 때문입니다.지금 이미 충분한 방법이 있습니다(C++03).예를 들어, 부울을 체크하는 것.

inline void mustBeBool(bool) { }
template<typename T> inline void mustBeBool(T t) { & (&t); } // Takes address of rvalue (&t)

// Use:
#define DifficultMacro(B) do { mustBeBool(B); foo(B); } while (false)

만약 당신이 신경쓰면.const그리고.volatile예선자들, 그리고 확실하게 하기를 원합니다.const그리고.volatile@Matt Joiner가 말하는 것처럼 유형의 일부도 비교 대상 유형과 정확히 일치합니다.

#include <type_traits>

static_assert(std::is_same<decltype(my_variable), uint64_t>::value, 
              "type must be `uint64_t`"); 

당신이 신경쓰지 않는 나는const, 그러나, 그리고 단순히 그 유형이 다음을 고려하지 않고 특정한 유형인지 확인하기를 원합니다.const, 대신에 다음과 같이 하십시오.참고:std::remove_const<>::type여기에 필요합니다.

static_assert(std::is_same<std::remove_const<decltype(my_variable)>::type, uint64_t>::value, 
              "type must be `uint64_t` OR `const uint64_t`");   

마찬가지입니다.volatile. 당신이 신경쓰지 않는다면,volatile유형의 일부, 당신은 그것을 무시할 수 있습니다.std::remove_volatile<>::type:

static_assert(std::is_same<std::remove_volatile<decltype(my_variable)>::type, uint64_t>::value, 
              "type must be `uint64_t` OR `volatile uint64_t`");

당신이 신경쓰지 않는다면,const오어volatile, 둘 다 제거할 수 있습니다.std::remove_cv<>::type:

static_assert(std::is_same<std::remove_cv<decltype(my_variable)>::type, uint64_t>::value, 
              "type must be `uint64_t` OR `const uint64_t` OR `volatile uint64_t` OR `volatile const uint64_t`");

또한 C++17 기준으로 다음을 수행할 수 있습니다.

  1. std::remove_cv_t<decltype(my_variable)>대신에std::remove_cv<decltype(my_variable)>::type, 그리고:
  2. std::is_same_v<some_type, another_type>대신에std::is_same<some_type, another_type>::value.

참조:

  1. static_assert를 사용하여 매크로에 전달된 유형을 확인합니다.
  2. https://en.cppreference.com/w/cpp/types/is_same
  3. https://en.cppreference.com/w/cpp/language/decltype
  4. https://en.cppreference.com/w/cpp/header/type_traits
  5. https://en.cppreference.com/w/cpp/types/remove_cv -std::remove_cv<>,std::remove_const<>,std::remove_volatile<>

관련:

  1. [위의 내용을 사용하는 나의 또 다른 답변.static_assert트릭] 스팬 스팬을 만드는 방법
  2. C의 정적 주장 [나 자신의 대답]
  3. C에서 정적 주장을 사용하여 매크로에 전달된 파라미터의 종류를 확인하는 방법 [나만의 질문]
  4. C의 매크로 인수 확인 유형
  5. *****C++ 템플릿 유형을 숫자로 제한

대부분의 매크로는 다음으로 대체할 수 있습니다.inline함수 및/또는 템플릿.대표적인 예로 지나치게 영리한 논증 크기 확인 포식스가 있습니다.isnanmacro는 C++0x의 템플릿입니다.오, 나쁜 예시지만, 당신은 그 생각을 알겁니다.

이 규칙의 주요 예외는 기본적으로 상위 언어 기능을 구현하는 매크로입니다.예를 들어, 더 스마트한 예외 처리, 공분산 또는 매개 변수화된 선언 집합이 있습니다.

합리적으로 표현할 수 없는 매크로가 다음과 같은 경우가 있습니다.inline함수 또는 템플릿은 더 똑똑한 종류의 전처리, 즉 코드 생성으로 대체될 수 있습니다.그러면 필요한 코드를 생성하는 스크립트가 어딘가에 있습니다.예를 들어 매크로와 템플릿을 사용하여 순수 C++로 옵션 클래스를 수행하는 것은 가능하지만, 이는 털이 많고, 그록이 더 쉽고, 유지보수가 더 용이한 대안으로 추가 빌드 단계와 여러 언어를 처리하는 비용으로 필수 클래스를 생성하는 스크립트를 사용할 수 있습니다.

건배!

언급URL : https://stackoverflow.com/questions/4021981/use-static-assert-to-check-types-passed-to-macro

반응형