Условные операторы C++ во время компиляции
Есть ли способ во время компиляции выбрать один из двух путей кода во время выполнения? Я знаю, что перегрузка функций может быть использована для выполнения этого подвига, но затем размер кода увеличивается, потому что обе мои функции скомпилированы и связаны с программой. Есть ли способ избежать такого размера накладных расходов?
По сути, я хочу сделать следующее:
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_abstract.hpp>
template <class T>
class X
{
public:
void copy_t(T &old_t)
{
//
// if T is abstract, (meaning that t is a pointer)
//
t = old_t.clone();
//
// else
//
t = old_t;
}
private:
typename boost::mpl::if_<boost::is_abstract<T>, T *, T>::type t;
};
Единственный известный мне способ включает перегруженные функции-члены:
template <class T>
class X
{
public:
void copy_t(T &old_t)
{
t = make_copy(old_t, t);
}
private:
T *make_copy(T &old_t, T *t)
{
return old_t.clone();
}
T &make_copy(T &old_t, T &t)
{
return old_t;
}
typename boost::mpl::if_<boost::is_abstract<T>, T *, T>::type t;
};
Но теперь два make_copy
функции-члены компилируются и связаны в программу, даже если X
может быть создан только с помощью параметра шаблона абстрактного класса, и в этом случае требуется только один из них.
1 ответ
Из ваших примеров видно, что функции являются членами шаблона класса. Если это так, они будут созданы только в том случае, если они действительно используются; если разрешение перегрузки всегда выбирает один из них, другой никогда не будет создан.
Это критическое правило для многих методов метапрограммирования. Нередко в таких случаях функция, для которой не был создан экземпляр, может вызвать ошибки времени компиляции, если он был создан.