Расширить имена типов параметров шаблона C ++ для сгенерированного кода - PullRequest
0 голосов
/ 13 февраля 2020

Возможно ли иметь шаблон C ++, в котором параметр шаблона может выступать в качестве префикса или суффикса для другого существующего (более длинного) имени типа. Я работаю с кодом, сгенерированным из IDL (Определение интерфейса), поэтому существует много сгенерированных классов со связанными именами. Например, если IDL определяет «Foo», у меня будет сформирован следующий список классов. Foo, FooReader, FooWriter, FooSerializer, ...

Я пытаюсь создать класс, содержащий переменную-член для каждого из этих сгенерированных типов ... В идеале я мог бы объявить объект с Wrapper<Foo> obj;

I может сделать что-то вроде этого:

#define EXPANDTEMPLATE(type) Wrapper<type, type##Reader, type##Writer, ... >

template <typename T, typename TReader, typename TWriter, ...> class Wrapper {
   T       var1;
   TReader var2;
   TWriter var3;
   ...
};

int main(){
   EXPANDTEMPLATE(Foo) obj;
   //do stuff
}

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

Есть ли лучшее / более чистое решение, чем создание шаблона с 15 параметрами?

Ответы [ 2 ]

0 голосов
/ 14 февраля 2020

Согласно документации OpenDDS, здесь :

В файле TypeTraits.h мы определяем шаблонную структуру TypeTraits для ссылки на различные объекты DDS, связанные с данной структурой образца данных.
// TypeTraits.h
template <typename DDS_STRUCT_T>
struct TypeTraits
{
};

#define DEFINE_TYPETRAITS(TYPE) \
template <> \
struct TypeTraits<TYPE> \
{ \
    typedef TYPE##TypeSupport TypeSupport; \
    typedef TYPE##TypeSupportImpl TypeSupportImpl; \
    typedef TYPE##DataWriter Writer; \
    typedef TYPE##DataReader Reader; \
};
Возвращаясь к DDSBase, теперь мы можем определить методы CreateWriter () и CreateReader () только с одним параметром шаблона ...

Вы можете использовать тот же подход в этом случае. Учитывая вышеупомянутый макрос, вы можете применить частичную специализацию шаблона; в вашем случае, вызывая этот макрос с DEFINE_TYPETRAITS(Foo). Возможно, вы захотите, чтобы ваш собственный макрос расширился до ваших пятнадцати вариантов, а не указанных c, но, учитывая это в документации OpenDDS, это должен быть более знакомый (теоретически) подход к людям, которые его используют. Также могут быть другие варианты использования вашего расширенного (или стандартного, если он работает) класса черт типа.

Если у вас есть эта специализация (DEFINE_TYPETRAITS для вашего интереса), вы можете создать простой шаблон, такой как это:

template<typename T>
struct Wrapper
{
    T var1;
    typename TypeTraits<T>::Reader var2;
    typename TypeTraits<T>::Writer var3;
    typename TypeTraits<T>::TypeSupport var4;
    typename TypeTraits<T>::TypeSupportImpl var5;
};

... и просто сделайте:

DEFINE_TYPETRAITS(Foo)
int main()
{
    Wrapper<Foo> obj;
}
0 голосов
/ 14 февраля 2020

Единственное, что у меня на уме - это использовать шаблонную специализацию .

Код может выглядеть как

#include <iostream>

using namespace std;

template <typename T>
class Reader;
template <typename T>
class Writer;

template <typename T>
class Wrapper {
    T data;
    Reader<T> reader;
    Writer<T> writer;
};

class Data {};
template<>
class Reader<Data> {};
template<>
class Writer<Data> {};

int main()
{
    Wrapper<Data> wrapper;
    static_cast<void>(wrapper);
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...