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 기준으로 다음을 수행할 수 있습니다.
std::remove_cv_t<decltype(my_variable)>
대신에std::remove_cv<decltype(my_variable)>::type
, 그리고:std::is_same_v<some_type, another_type>
대신에std::is_same<some_type, another_type>::value
.
참조:
- static_assert를 사용하여 매크로에 전달된 유형을 확인합니다.
- https://en.cppreference.com/w/cpp/types/is_same
- https://en.cppreference.com/w/cpp/language/decltype
- https://en.cppreference.com/w/cpp/header/type_traits
- https://en.cppreference.com/w/cpp/types/remove_cv -
std::remove_cv<>
,std::remove_const<>
,std::remove_volatile<>
관련:
- [위의 내용을 사용하는 나의 또 다른 답변.
static_assert
트릭] 스팬 스팬을 만드는 방법 - C의 정적 주장 [나 자신의 대답]
- C에서 정적 주장을 사용하여 매크로에 전달된 파라미터의 종류를 확인하는 방법 [나만의 질문]
- C의 매크로 인수 확인 유형
- *****C++ 템플릿 유형을 숫자로 제한
대부분의 매크로는 다음으로 대체할 수 있습니다.inline
함수 및/또는 템플릿.대표적인 예로 지나치게 영리한 논증 크기 확인 포식스가 있습니다.isnan
macro는 C++0x의 템플릿입니다.오, 나쁜 예시지만, 당신은 그 생각을 알겁니다.
이 규칙의 주요 예외는 기본적으로 상위 언어 기능을 구현하는 매크로입니다.예를 들어, 더 스마트한 예외 처리, 공분산 또는 매개 변수화된 선언 집합이 있습니다.
합리적으로 표현할 수 없는 매크로가 다음과 같은 경우가 있습니다.inline
함수 또는 템플릿은 더 똑똑한 종류의 전처리, 즉 코드 생성으로 대체될 수 있습니다.그러면 필요한 코드를 생성하는 스크립트가 어딘가에 있습니다.예를 들어 매크로와 템플릿을 사용하여 순수 C++로 옵션 클래스를 수행하는 것은 가능하지만, 이는 털이 많고, 그록이 더 쉽고, 유지보수가 더 용이한 대안으로 추가 빌드 단계와 여러 언어를 처리하는 비용으로 필수 클래스를 생성하는 스크립트를 사용할 수 있습니다.
건배!
언급URL : https://stackoverflow.com/questions/4021981/use-static-assert-to-check-types-passed-to-macro
'source' 카테고리의 다른 글
크로스 플랫폼 모바일 개발에 대해 어떤 작업이 이루어졌습니까? (0) | 2023.11.02 |
---|---|
R: RMySQL을 사용하여 MySQL 오류에 테이블 쓰기 (0) | 2023.11.02 |
Swift XCTest UI에서 테스트 사이에 앱을 재설정할 수 있는 방법이 있습니까? (0) | 2023.11.02 |
jquery는 Safari에서만 마진 문제 생성 (0) | 2023.11.02 |
Angularjs에서 문자열 보간 내에서 줄 바꿈을 얻는 방법 (0) | 2023.11.02 |