В некоторых случаях мне может потребоваться использование одного и того же поведения/кода со значениями, которые иногда известны во время выполнения и во время компиляции. Это приводит к повторению кода:
template<int TValue> struct CompileTime
{
int duplicate() { return TValue * 2; }
};
struct RunTime
{
int value;
RunTime(int mValue) : value{mValue} { }
int duplicate() { return value * 2; }
};
int main()
{
// I need to duplicate a compile-time known value first...
CompileTime<2>{}.duplicate();
// And now I need to duplicate a run-time value...
int value; std::cin >> value;
RunTime{value}.duplicate();
}
Очевидно, что пример действительно глупый, но есть ли способ избежать повторения поведения duplicate()
? (Однако значение необходимо сохранить.)
В идеале я бы хотел написать:
int main()
{
// 2 is known at compile-time, calls a "templatized" version of 'duplicate'
UnknownTime<2>{}.duplicate();
// 'value' is known at run time, calls a "run-time" version of 'duplicate'
int value; std::cin >> value;
UnknownTime<value>{}.duplicate();
}
Вы не можете создавать шаблоны во время выполнения, однако вы можете полностью constexpr
шаблоны и использовать С++ 11 constexpr
, который был добавлен на язык именно для этой цели:
struct AnyTime
{
int value;
constexpr AnyTime(int mValue) : value{mValue} { }
constexpr int duplicate() const { return value * 2; }
};
int main()
{
constexpr int compileTime = AnyTime{2}.duplicate();
int value; std::cin >> value;
int runTime = AnyTime{value}.duplicate();
}
В таких случаях, как duplicate
вы можете перейти к использованию функций, а не к классам или структурам:
template<int TValue>
int duplicate()
{
return TValue * 2;
}
int duplicate(int value)
{
return value * 2;
}
Теперь вы можете сказать:
int main()
{
// 2 is known at compile-time, calls a "templatized" version of 'duplicate'
int value1 = duplicate<2>();
// 'value' is known at run time, calls a "run-time" version of 'duplicate'
int value; std::cin >> value;
int value2 = duplicate(value);
}
duplicate()
какconst
, а не простоconstexpr
, чтобы быть совместимым с C ++ 14. В противном случаеconstexpr AnyTime at{2}; at.duplicate();
не скомпилируется.constexpr
решает эту проблему.