문제

당신은 어디에 예를 들여 줄 수 있습니까? static_assert(...) 'C++0x' 우아하게 문제를 해결할 수 있습니까?

런타임에 익숙합니다 assert(...). 언제 선호해야합니까? static_assert(...) 정기적으로 assert(...)?

또한, boost 무언가가 있습니다 BOOST_STATIC_ASSERT, 그것은 동일합니다 static_assert(...)?

도움이 되었습니까?

해결책

내 머리 꼭대기에서 ...

#include "SomeLibrary.h"

static_assert(SomeLibrary::Version > 2, 
         "Old versions of SomeLibrary are missing the foo functionality.  Cannot proceed!");

class UsingSomeLibrary {
   // ...
};

그것을 가정합니다 SomeLibrary::Version 존재하기보다는 정적 콘트로로 선언됩니다. #defineD (C ++ 라이브러리에서 기대할 수있는대로).

실제로 컴파일 해야하는 것과는 대조적입니다 SomeLibrary 그리고 코드, 모든 것을 연결하고 실행 파일 만 실행하십시오. 그 다음에 호환되지 않는 버전을 컴파일하는 데 30 분을 보냈다는 것을 알기 위해 SomeLibrary.

@arak, 귀하의 의견에 대한 응답으로 : 예, static_assert 그 모습에서 어디서나 앉아 있습니다.

class Foo
{
    public: 
        static const int bar = 3;
};

static_assert(Foo::bar > 4, "Foo::bar is too small :(");

int main()
{ 
    return Foo::bar;
}
$ g++ --std=c++0x a.cpp
a.cpp:7: error: static assertion failed: "Foo::bar is too small :("

다른 팁

정적 인제는 컴파일 시간에 주장을하는 데 사용됩니다. 정적 어설 션이 실패하면 프로그램은 단순히 컴파일하지 않습니다. 예를 들어, 코드별로 일부 기능을 구현하는 경우와 같이 다른 상황에서 유용합니다. unsigned int 정확히 32 비트를 가진 물체. 당신은 이와 같은 정적 인제를 넣을 수 있습니다

static_assert(sizeof(unsigned int) * CHAR_BIT == 32);

코드에서. 다른 크기의 다른 플랫폼에서 unsigned int 컴파일을 입력하면 실패하므로 개발자가 코드의 문제가있는 부분에주의를 기울이고 재 구현하거나 다시 확인하도록 조언합니다.

다른 예를 들어, 당신은 몇 가지 필수 값을 void * 함수에 대한 포인터 (해킹이지만 때때로 유용함) 및 적분 값이 포인터에 맞는지 확인하려고합니다.

int i;

static_assert(sizeof(void *) >= sizeof i);
foo((void *) i);

당신은 그것을 자산하고 싶을 수도 있습니다 char 유형이 서명되었습니다

static_assert(CHAR_MIN < 0);

또는 음수 값을 가진 그 적분 분할이 0으로 향합니다.

static_assert(-5 / 2 == -2);

등등.

많은 경우에 런타임 어설 션은 정적 어설 션 대신에 사용할 수 있지만 런타임 어설 션은 런타임과 제어가 어설 션을 통과 할 때만 작동합니다. 이러한 이유로 실패한 런타임 주장은 휴면 상태가 될 수 있으며, 장기간 동안 감지되지 않을 수 있습니다.

물론, 정적 주장의 표현은 컴파일 타임 상수 여야합니다. 런타임 가치가 될 수는 없습니다. 런타임 값의 경우 다른 선택은 없지만 평범한 것을 사용하십시오. assert.

컴파일러 동작, 헤더, 라이브 및 내 코드에 대한 가정이 올바른지 확인하기 위해 사용합니다. 예를 들어 여기서 구조물이 예상 크기로 올바르게 포장되었는지 확인합니다.

struct LogicalBlockAddress
{
#pragma pack(push, 1)
    Uint32 logicalBlockNumber;
    Uint16 partitionReferenceNumber;
#pragma pack(pop)
};
BOOST_STATIC_ASSERT(sizeof(LogicalBlockAddress) == 6);

클래스 포장에서 stdio.h'에스 fseek(), 나는 바로 가기를 가져 갔다 enum Origin 그리고 그 바로 가기가 stdio.h

uint64_t BasicFile::seek(int64_t offset, enum Origin origin)
{
    BOOST_STATIC_ASSERT(SEEK_SET == Origin::SET);

당신은 선호해야합니다 static_assert ~ 위에 assert 동작이 컴파일 타임에 정의 된 경우, 위에서 제시 한 예제와 같이 런타임이 아니라. 이것이 어디에 있는가 ~ 아니다 이 사례에는 매개 변수 및 반환 코드 확인이 포함됩니다.

BOOST_STATIC_ASSERT 조건이 충족되지 않은 경우 불법 코드를 생성하는 사전 C ++ 0X 매크로입니다. 의도는 동일하지만 동일합니다 static_assert 표준화되며 더 나은 컴파일러 진단을 제공 할 수 있습니다.

BOOST_STATIC_ASSERT 크로스 플랫폼 래퍼입니다 static_assert 기능.

현재 수업에서 "개념"을 시행하기 위해 static_assert를 사용하고 있습니다.

예시:

template <typename T, typename U>
struct Type
{
  BOOST_STATIC_ASSERT(boost::is_base_of<T, Interface>::value);
  BOOST_STATIC_ASSERT(std::numeric_limits<U>::is_integer);
  /* ... more code ... */
};

위의 조건 중 하나가 충족되지 않으면 컴파일 시간 오류가 발생합니다.

하나의 사용 static_assert 구조 (네트워크 또는 파일과 같은 외부 세계와의 인터페이스)가 정확히 예상되는 크기인지 확인하는 것일 수 있습니다. 이것은 누군가가 결과를 실현하지 않고 구조에서 구성원을 추가하거나 수정하는 경우를 포착 할 것입니다. 그만큼 static_assert 그것을 집어 들고 사용자에게 경고합니다.

개념이 없으면 사용할 수 있습니다 static_assert 예를 들어 템플릿에서 간단하고 읽기 쉬운 컴파일 타임 유형 확인의 경우 :

template <class T>
void MyFunc(T value)
{
static_assert(std::is_base_of<MyBase, T>::value, 
              "T must be derived from MyBase");

// ...
}

이것은 원래 질문에 직접적인 답변을받지는 않지만 C ++ 11 이전에 이러한 컴파일 시간 검사를 시행하는 방법에 대한 흥미로운 연구를합니다.

2 장 (섹션 2.1) 현대 C ++ 디자인 작성자 : Andrei Alexanderscu는 이와 같은 컴파일 타임 어설

template<int> struct CompileTimeError;
template<> struct CompileTimeError<true> {};

#define STATIC_CHECK(expr, msg) \
{ CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; } 

Macro static_check () 및 static_assert () 비교

STATIC_CHECK(0, COMPILATION_FAILED);
static_assert(0, "compilation failed");
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top