У меня есть шаблон, который я хотел бы условно скомпилировать в зависимости от типа аргумента. Я только забочусь о дифференциации между "Простыми Данными" (POD), т.е. целые числа, и т.д. или классы/структуры. Я использую C++ VS2008 в Windows.
template<T>
class foo
{
void bar(T do_something){
#if IS_POD<T>
do something for simple types
#else
do something for classes/structs
#endif
}}
Я смотрел на библиотеку повышения, и я вижу, что они, кажется, имеют то, что я хочу. Однако я не понимаю что правильный синтаксис для #if
оператор был бы.
Любая справка ценилась бы.
Отредактируйте---После чтения ответов, я вижу, что пропустил что-то в своем определении вопроса. Класс foo
шаблонный класс, который только должен инстанцировать версию bar
это корректно для class type T
. Я искал решение, которое может быть разрешено время компиляции. Надежда это разрешает мою проблему.
Вы можете сделать это без enable_if, потому что все, что вам нужно, это диспетчеризация в зависимости от признаков типа. enable_if используется для добавления/удаления инстанций шаблона в/из разрешения перегрузки. Вы можете использовать черты вызова, чтобы выбрать лучший метод передачи объектов в вашу функцию. Как правило, объекты следует передавать по ссылке, тогда как POD передается по значению. call_traits позволяет выбирать между const и non-const ссылками. В приведенном ниже коде используется ссылка const.
#include <boost/type_traits.hpp>
#include <boost/call_traits.hpp>
template <typename T>
class foo {
public:
void bar(typename boost::call_traits<T>::param_type obj) {
do_something(obj, boost::is_pod<T>());
}
private:
void do_something(T obj, const boost::true_type&)
{
// do something for POD
}
void do_something(const T& obj, const boost::false_type&)
{
// do something for classes
}
};
Вы не можете решить это с помощью препроцессора, поскольку он не знает о C++. (Это тупой инструмент для замены текста). Используйте шаблоны для этого.
Предположим, что IsPod
возвращает что-то похожее на Boolean
/Boolean
:
template<T>
class foo
{
void do_something(T obj, Boolean<true> /*is_pod*/)
{
// do something for simple types
}
void do_something(T obj, Boolean<false> /*is_pod*/)
{
// do something for classes/structs
}
void bar(T obj)
{
do_something(obj, IsPod<T>::result());
}
}
Использование препроцессора здесь невозможно. Взгляните на Библиотеку Boost Enable If .
В частности, в вашем случае это будет выглядеть (не проверено):
void bar (typename enable_if <is_pod <T>, T>::type do_something)
{
// if is POD
}
void bar (typename disable_if <is_pod <T>, T>::type do_something)
{
// if not
}