このようなものが役立ちます:
template <typename T>
class HeapWrapper
{
#ifdef USE_STACK
T obj_;
#else
T *obj_;
#endif
public:
#ifdef USE_STACK
HeapWrapper() : obj_() {}
#else
HeapWrapper() : obj_(new T()) {}
#endif
#ifdef USE_STACK
const T& obj() const
{ return obj_; }
T& obj() const
{ return obj_; }
#else
const T& obj() const
{ return *obj_; }
T& obj() const
{ return *obj_; }
#endif
};
ただし、これにより、デフォルトのコンストラクターのみを持つオブジェクトに制限されることに注意してください。ラップされたクラスは、ラッパー クラスによる可変個引数テンプレート関数Init(...)
によって転送できる関数を提供できます(または、必要なアリティごとに a を追加するだけです)。template <typename T1, template T2, [etc]> Init(const T1 &x1, cons tT2 &x2)
template <typename T1>
void Init(const T1& x1)
{
#ifdef USE_STACK
obj_.Init(x1);
#else
obj_->Init(x1);
#endif
}
template <typename T1, typename T2>
void Init(const T1& x1, const T2& x2)
{
#ifdef USE_STACK
obj_.Init(x1, x2);
#else
obj_->Init(x1, x2);
#endif
}
コンパイラに可変個引数テンプレートが既にある場合のボーナス ポイント:
template<typename... T>
void foo(const T&... values) {
#ifdef USE_STACK
obj_.Init(values...);
#else
obj_->Init(values...);
#endif
}