В C/C++ определение переменной не есть её инициализация. Верно для фундаментальных (или встроенных) типов. Для пользовательских типов всегда (если не указано ничего иного) вызывается конструктор по умолчанию, в котором можно принять необходимые меры по инициализации.
Враппер помогает решать задачи инициализации переменной при её объявлении, а так же при использовании в контейнерах типа std::map
или std::multimap
, когда нужно проверить переменную для ключа, которого ещё нет (при обращении через operator[]
создастся новое значение, для которого вызовется конструктор по умолчанию).
Код:
/**
* Can be used for built-in types only (like int, char, long and so on)
*/
template <typename T, T initialValue = 0>
struct BuiltInTypeWrapper
{
BuiltInTypeWrapper()
: value(initialValue)
{}
BuiltInTypeWrapper(T v)
: value(v)
{}
bool isValid() const
{
return (value != initialValue);
}
void reset()
{
value = initialValue;
}
operator T&()
{
return value;
}
operator T const&() const
{
return value;
}
BuiltInTypeWrapper& operator=(T v)
{
value = v;
return *this;
}
T value;
};
Для временных меток в FFMPEG можно использовать так:
/**
* Simple wrapper for time stamp values
*/
typedef BuiltInTypeWrapper<int64_t, AV_NOPTS_VALUE> TsWrapper;
т.е. при объявлении переменной типа TsWrapper она автоматом станет инициализирована в AV_NOPTS_VALUE
.
А просто для int
так:
typedef BuiltInTypeWrapper<int> Integer;
При этом при объявлении переменной типа будет она будет инициализирована в 0.
За счёт определения оператора приведения типа и перегруженному оператору присваивания использование обёрнутого значения мало отличается от необёрнутого:
typedef BuiltInTypeWrapper<int64_t, AV_NOPTS_VALUE> TsWrapper;
...
void foo(int64_t &v)
{
clog << v << endl;
}
...
TsWrapper wrappedValue;
int64_t value = 255;
wrappedValue = value; // 1
if (wrappedValue == value) // 2
...
foo(wrappedValue) // 3
wrappedValue++; // 4, аналогично для префиксной формы
wrappedValue--; // 5, аналогично для префиксной формы
wrappedValue += 5; // 6
wrappedValue -= 5; // 7
В общем и целом практически повторяет поведение оригинального типа.
Кто какие нюансы видит?
PS тестировалось на gcc 4.7.2