Недопустимое значение по умолчанию - это, по сути, вариант вашего дизайна. Объект недействителен, когда он создан. Вам следует избегать этого, когда это разумно. Ни в коем случае нельзя избегать этого «любой ценой».
Некоторые проблемы требуют запуска в вариантном состоянии. В этом случае вы должны мысленно обсудить это недопустимое значение. Если вы избегаете называть его, вы активно делаете свой код менее выразительным. Подумайте об этом с точки зрения общения между вами и человеком, которому позже придется поддерживать код.
Разбираться с этим по ветру раздражает. Вы начинаете с вариантного состояния, но к тому времени, когда оно актуально, вы надеетесь, что это уже не вариант. Стратегия, которую я предпочитаю, - это позволить пользователям игнорировать вариантное состояние и просто бросать, если я допустил ошибку.
namespace FooType {
enum EnumValue {
INVALID = 0
,valid
};
}
struct Foo {
Foo() : val(FooType::INVALID) {}
FooType::EnumValue get() const {
if (val == FooType::INVALID)
throw std::logic_error("variant Foo state");
return val;
}
FooType::EnumValue val;
};
Это освобождает ваших пользователей от необходимости рассуждать о вашей дисперсии, за что стоит бороться.
Если вам это не сойдет с рук, я обычно предпочитаю перейти на безопасные и небезопасные интерфейсы.
struct Foo {
Foo() : val(FooType::INVALID) {}
bool get(FooType::EnumValue& val_) const {
if (val == FooType::INVALID)
return false;
val_ = val;
return true;
}
FooType::EnumValue get() const {
FooType::EnumValue val_;
if (!get(val_))
throw std::logic_error("variant Foo state");
return val_;
}
FooType::EnumValue get_or_default(FooType::EnumValue def) const {
FooType::EnumValue val_;
if (!get(val_))
return def;
return val_;
}
FooType::EnumValue val;
};
Интерфейсы такого типа хороши для таких вещей, как базы данных, где могут ожидаться нулевые значения.
person
Tom Kerr
schedule
19.12.2012