为生成的代码扩展 C++ 模板参数类型名称

Extend C++ template parameter type names for generated code

是否可以有一个 C++ 模板,其中模板参数可以充当另一个现有(更长)类型名称的前缀或后缀。我正在处理从 IDL(接口定义)生成的代码,因此生成的许多 classes 具有相关名称。例如,如果 IDL 定义了 "Foo",我将生成以下 classes 列表。 Foo, FooReader, FooWriter, FooSerializer, ...

我正在尝试创建一个 class,其中包含每个生成类型的成员变量...理想情况下,我可以使用 Wrapper<Foo> obj;

声明对象

我可以这样做:

#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
}

在我的例子中,默认构造函数不会成为问题,所以这个 有效 ,但我更喜欢这样的解决方案不会带领代码维护者跟踪我并打断我的腿。

是否有 better/cleaner 解决方案而不是创建包含 15 个参数的模板?

我心里唯一的想法就是用template specialization.

代码看起来像

#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);
} 

根据 OpenDDS 文档,here:

In the file TypeTraits.h we define a templated struct, TypeTraits, to reference the various DDS entities associated with a given data sample structure.
// 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; \
};
Returning to DDSBase, we can now define CreateWriter() and CreateReader() methods with just one template parameter ...

在这种情况下,您可以使用相同的方法。鉴于上述宏,您可以应用部分模板特化;在您的情况下,通过使用 DEFINE_TYPETRAITS(Foo) 调用此宏。您可能希望您自己的宏扩展到您的 15 个变体而不是这些特定的变体,但鉴于这在 OpenDDS 文档中,它应该是使用它的人更熟悉的方法(理论上)。您的扩展(或默认,如果有效)类型特征可能还有其他用途 class.

一旦你有了这个专业(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;
}