Использование проектов самое с открытым исходным кодом GetText с этой целью. Я не знаю, как и использовалось ли это когда-либо на.Net проекте прежде.
С ума сойти ...
#include "SomeLibrary.h"
static_assert(SomeLibrary::Version > 2,
"Old versions of SomeLibrary are missing the foo functionality. Cannot proceed!");
class UsingSomeLibrary {
// ...
};
Предполагая, что SomeLibrary :: Version
объявлен как статическая константа, а не как #define
d (как и следовало ожидать от библиотеки 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 :("
Я использую его, чтобы убедиться, что мои предположения о поведении компилятора, заголовках, библиотеках и даже моем собственном коде верны. Например, здесь я проверяю, что структура была правильно упакована до ожидаемого размера.
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
стандартизирован и может обеспечить лучшую диагностику компилятора.
Статическое утверждение используется для выполнения утверждений во время компиляции. Когда статическое утверждение терпит неудачу, программа просто не компилируется. Это полезно в различных ситуациях, например, если вы реализуете некоторые функции с помощью кода, который критически зависит от объекта 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);
или это целое деление с округлением отрицательных значений в сторону нуля
static_assert(-5 / 2 == -2);
И т. д.
Утверждения времени выполнения во многих случаях могут использоваться вместо статических утверждений, но утверждения времени выполнения работают только во время выполнения и только тогда, когда управление передается над утверждением. По этой причине неудачное утверждение во время выполнения может оставаться бездействующим, необнаруженным в течение продолжительных периодов времени.
Конечно, выражение в статическом утверждении должно быть константой времени компиляции. Это не может быть значением времени выполнения. Для значений времени выполнения у вас нет другого выбора, кроме как использовать обычный assert
.
Конечно, выражение в статическом утверждении должно быть константой времени компиляции. Это не может быть значением времени выполнения. Для значений времени выполнения у вас нет другого выбора, кроме как использовать обычный assert
.
Конечно, выражение в статическом утверждении должно быть константой времени компиляции. Это не может быть значением времени выполнения. Для значений времени выполнения у вас нет другого выбора, кроме как использовать обычный assert
.
Одно использование static_assert
может гарантировать, что структура (то есть интерфейс с внешним миром, например сеть или файл) имеет именно тот размер, который вы ожидаете. Это позволит выявить случаи, когда кто-то добавляет или изменяет член структуры, не осознавая последствий. static_assert
поднимет его и предупредит пользователя.
static_assert
поднимет его и предупредит пользователя. Это позволит выявить случаи, когда кто-то добавляет или изменяет член структуры, не осознавая последствий. 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 ... */
};
Это вызвало ошибку времени компиляции, если какая-либо из вышеуказанных условий не выполняется.