【发布时间】:2014-11-23 00:03:18
【问题描述】:
我有一个这样的模板类:
template <class TType> class Class1;
这个类被用于许多其他类:
class Class2 {
Class1 _class1; // How to pass the template parameter of Class1 in a clean way ?
};
// Same for Class3, Class4, ...
问题是Class1的模板参数必须由客户端代码选择,所以我不能直接这样说:
class Class2 {
Class1<OneType> _class1; // Not correct, template parameter must be chosen by client code
};
所以正确的方法是将 Class2 也设置为模板类:
template <class TTypeClass1> class Class2 {
Class1<TTypeClass1> _class1;
};
这种技术的问题是所有使用Class1的类都必须是模板类,所以我们污染了其他类的代码来传递Class1的模板参数,如果这些类是由许多模板类和许多模板组成的,那就更糟了参数。
我发现了另一种我认为更清洁的方法:
template <class TTypeClass1 /* And possible other parameters */> struct ClientConfiguration {
// Declaration of EntityManager
typedef Class1<TTypeClass1> Class1Typed;
};
// Configuration defined by client code
typedef ClientConfiguration<OneTypeForClass1 /* And possible other parameters */> CurrentClientConfiguration;
class Class2 {
CurrentClientConfiguration::Class1Typed _class1;
}
但是有没有更好的方法来做到这一点?
【问题讨论】:
-
“但是有没有更好的方法来做到这一点?” 更好的方法和要求是什么?为什么在这里引入可变参数模板参数?请您稍微澄清一下您的问题。
-
您的
ClientConfiguration不会按您希望的方式工作。您似乎假设在同一个程序中可以有不同的Class2“实例化”,根据CurrentClientConfiguration::Class1Typed的不同定义编译。如果您真的尝试这样做,您的程序将违反一个定义规则,因此会表现出未定义的行为。 -
您的库代码具有任何模板代码的所有常见缺点,即它必须作为头文件提供并由用户编译,但没有普通模板代码的清晰和明确性。 Class2 取决于用户提供的定义,您可以仅通过查看它来确认或否认吗?另外,您打算如何实现这个
// Configuration defined by client code位?通过#include输入一个文件,比如usercode.h并让用户提供一个文件?如果是这种情况,您可以完全省略模板,只需让用户创建一些 typedef。 -
我不确定我是否在这里看到了需要解决的问题。如果类
A引用参数化类型B,则A本身必须是参数化的。否则,您可以(并且应该)在其对B的引用中硬编码类型参数。如果必须对A进行参数化,为什么要跨越障碍去尝试找到一种更模糊的表达方式呢?诚然,带有模板的 C++ 编译模型使这种传播有些痛苦,但这些就是你所拥有的语义,这就是你在 C++ 中表达这些语义的方式。 -
template类型参数是某些代码的编译时参数。为什么选择编译时参数而不是运行时?如果“性能”,您是否证明这是一个瓶颈,或者只是假设并喷出代码?如果您已经证明它是一个瓶颈,那么该选择是否可以被类型擦除?即,您能否抽象出对运行时接口的性能至关重要的部分,然后从其他地方注入该选择?