Существует два вида плавания reflection
.
template-tricks
. Используйте boost::type_traits
для многих вещей (например, проверка целостности типа). Для проверки существования функции-члена используйте Возможно ли написать шаблон для проверки существования функции? . Для проверки наличия определенного вложенного типа используйте plain SFINAE . Если вы скорее ищете способы достижения 1), например, посмотрите, сколько методов имеет класс, или как получить строковое представление идентификатора класса, тогда я боюсь, что есть нет стандартного способа C ++ для этого. Вы должны использовать либо
C ++ создается с учетом скорости. Если вам нужна проверка высокого уровня, например, C # или Java, то, боюсь, я должен сказать вам, что нет никакого способа без каких-либо усилий.
Ну, это, по сути, прямая копия из стандарта
3.4.1 1 поведение, определяемое реализацией неопределенное поведение, где каждая реализация документирует, как выбор сделан
2 ПРИМЕР Примером определенного реализацией поведения является распространение старшего бита, когда знаковое целое число сдвигается вправо.
3.4.3 1 неопределенное поведение поведение, при использовании не переносимой или ошибочной программной конструкции или ошибочных данных, в отношении которых настоящий международный стандарт стандарт не предъявляет никаких требований
2 ПРИМЕЧАНИЕ Возможное неопределенное поведение варьируется от игнорирования ситуации полностью с непредсказуемыми результатами, до поведения во время перевода или выполнения программы в документированном образом, характерным для среды (с или без выдачей диагностического сообщения), к прекращение перевода или выполнения (с выдачей диагностического сообщения).
3 ПРИМЕР Примером неопределенного поведения является поведение при целочисленном переполнении.
3.4.4 1 неопределенное поведение использование неопределенного значения или другое поведение когда настоящий международный стандарт предусматривает две или более возможностей и не накладывает никаких дополнительных требований на который выбирается в любом случае
2 ПРИМЕР Примером неопределенного поведения является порядок, в котором аргументы функции оцениваются.
Undefined Behavior vs. Unspecified Behavior имеет краткое описание этого.
Их заключительное резюме:
Подводя итог, можно сказать, что неопределенное поведение - это обычно то, о чем не стоит беспокоиться, если только от вашего программного обеспечения не требуется переносимость. И наоборот, неопределенное поведение всегда нежелательно и никогда не должно возникать.
Возможно, простые формулировки легче понять, чем строгое определение стандартов.
поведение, определяемое реализацией
Язык говорит, что у нас есть типы данных. Поставщики компиляторов указывают, какие размеры они должны использовать, и предоставляют документацию о том, что они сделали.
неопределенное поведение
Вы делаете что-то не так. Например, у вас есть очень большое значение в int
, которое не помещается в char
. Как вы поместите это значение в char
? на самом деле нет возможности! Все может случиться, но наиболее разумным было бы взять первый байт этого int и поместить его в char
. Просто неправильно делать это для присвоения первого байта, но это то, что происходит под капотом.
неопределенное поведение
Какая из этих двух функций выполняется первой?
void fun(int n, int m);
int fun1()
{
cout << "fun1";
return 1;
}
int fun2()
{
cout << "fun2";
return 2;
}
...
fun(fun1(), fun2()); // which one is executed first?
В языке не указывается оценка, слева направо или справа налево! Таким образом, неопределенное поведение может или не может приводить к неопределенному поведению, но определенно ваша программа не должна вызывать неопределенное поведение.
@eSKay Я думаю, что ваш вопрос стоит отредактировать ответ, чтобы уточнить больше:)
for
fun (fun1 (), fun2 ());
- это не поведение "реализация определена"? В конце концов, компилятор должен выбрать один или другой курс?
Разница между определенным реализацией и неопределенным в том, что компилятор должен выбрать поведение в первом случае, но не обязательно во втором случае. Например, реализация должна иметь одно и только одно определение sizeof (int)
.Таким образом, нельзя сказать, что sizeof (int)
равно 4 для одной части программы и 8 для других. В отличие от неопределенного поведения, когда компилятор может сказать «ОК», я буду оценивать эти аргументы слева направо, а аргументы следующей функции оцениваются справа налево. Это может происходить в одной программе, поэтому называется неопределенным . Фактически, C ++ можно было бы упростить, если бы были указаны некоторые из неопределенных вариантов поведения. Взгляните на Dr. Ответ Страуструпа на этот вопрос :
Утверждается, что разница между тем, что может быть произведено, предоставляя компилятору эту свободу, и , требующим «обычного слева направо». правильная оценка "может иметь значение. Я не убежден, но с бесчисленными компиляторами "там", пользующимися свободой, и некоторыми людьми , страстно защищающими эту свободу, {{1 }} изменения будут трудными и могут потребоваться десятилетия, чтобы проникнуть в далекие уголки миров C и C ++ . Я разочарован тем, что не все компиляторы предупреждают о таком коде, как ++ i + i ++. Точно так же не указан порядок оценки аргументов .
ИМО, слишком много "вещей" оставлено неопределенным, неопределенным, определенным реализацией и т. Д. Однако это легко сказать и даже дать {{1 }} примеры, но их трудно исправить. Следует также отметить, что не так уж и сложно избежать большинства проблем и создать переносимый код.