Условная компиляция с использованием типовых черт Boost - PullRequest
7 голосов
/ 30 июля 2010

У меня есть шаблон, который я хотел бы условно скомпилировать в зависимости от типа аргумента. Меня интересует только различие между «Простыми старыми данными» (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. Я искал решение, которое можно решить во время компиляции. Надеюсь, это решит мою проблему.

Ответы [ 3 ]

7 голосов
/ 30 июля 2010

Вы можете сделать это без enable_if , потому что все, что вам нужно, это отправлять в зависимости от типа черты. enable_if используется для добавления / удаления экземпляров шаблона в / из разрешения перегрузки. Вы можете использовать черты вызова, чтобы выбрать лучший метод для передачи объектов в вашу функцию. Как правило, объекты должны передаваться по ссылке, а POD - по значению. call_traits позволяет выбирать между const и неконстантными ссылками. Код ниже использует const reference.

#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
    }
};
3 голосов
/ 30 июля 2010

Вы не можете решить эту проблему с препроцессором, так как он не знает о C ++.(Это простой инструмент для замены текста.) Используйте шаблоны для этого.

Предположим, IsPod<T>::result возвращает что-то похожее Boolean<true> / Boolean<false>:

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());
    }
}
0 голосов
/ 30 июля 2010

Использование препроцессора здесь невозможно. Взгляните на Boost Enable If library вместо.

В частности, в вашем случае это будет выглядеть (не проверено):

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...