Обнаружить наличие шаблонных методов и свободных функций - PullRequest
2 голосов
/ 25 февраля 2012

У меня есть набор специализированных шаблонов. Теперь я хочу создать специализированные шаблоны для двух случаев:

  1. Если в классе / структуре присутствует определенный метод (достаточно определения имени).

  2. Если присутствует определенная свободная функция (в этом случае должны быть обнаружены имя и часть подписи).

Проблема в том, что и свободная функция, и метод класса будут также шаблонизированы. Это для своего рода архитектуры сериализации, и у меня есть несколько способов сериализации, поэтому параметром шаблона для метода / функции будет стратегия сериализации, предоставляемая другим специализированным шаблоном. Я не могу сделать стратегию абстрактной базой, потому что позже будут вызваны другие шаблонные методы, а виртуальные и шаблоны не будут смешиваться.

Вот пример того, что мне нужно:

template<typename T>
struct strategy1 {};

template<>
struct strategy1<char> {
  void call() {
    // Do char specific stuff
  }
};

class foo_specialized {
/* ... */
};

template<>
struct strategy1<foo_specialized> {
  void call() {
    // do foo_specialized stuff
  }
};

class foo_method {
public:
  template< Typename T>
  void serialize( T & t ) {
    // use T here to do stuff
  }
};

/* This should be used for foo_method */
template< typename T >
struct strategy1</* don't know what to put here */>
  struct strategy1_helper{
    template<typename T2>
    void call( T2 t ) {
       // do stuff with t
    }
   };

  void call( const T & t ) {
    t.serialize( strategy1_helper() );
  } 
};

class foo_function {
/* ... */
};

template<typename T>
void serialize( const foo_function & foo, T & t ) {
  // use T here
}

/* This should be used for foo_function */
template< typename T >
struct strategy1</* don't know what to put here */>
  struct strategy1_helper{
    template<typename T2>
    void call( T2 t ) {
       // do stuff with t
    }
   };

  void call( const T & t ) {
    serialize( t, strategy1_helper() );
  } 
};

Можно ли каким-то образом заставить механизм разрешения шаблонов выбирать эти две последние специализации на основе фактического предоставленного аргумента? Или есть более чистый дизайн, чтобы достигнуть этого?

Я могу легко использовать черты типа и средства метапрограммирования, предоставляемые C ++ 11, поэтому мне не нужно выполнять шаги SFINAE самостоятельно.

1 Ответ

2 голосов
/ 25 февраля 2012

Решение требует использования SFINAE для определения потенциального типа возврата указанной функции-члена. Трюк использует перегрузку через многоточие в случае сбоя доступа к указателю элемента.

Для правильной реализации требуется также несколько макросов. У меня есть такая реализация, лежащая здесь:

https://github.com/jfalcou/boosties/tree/master/introspection/boost

Теперь, в мышлении C ++ 11, кое-что из этого, безусловно, может превратиться в обнаружение на основе decltype, но макрос все еще необходим, так как вам нужен способ извлечь имя члена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...