【发布时间】:2012-01-16 20:31:38
【问题描述】:
我正在为我们在其他代码中定义的一堆类编写一个通用包装类。我试图弄清楚 C++ 中是否有一种方法可以编写一个可以将模板参数存储为变量的模板类。这是我希望看到的工作示例:
template < class C > class generic {
public:
C obj; // used for custom type processing
template < class T > T other; // <- changeable variable (or something)
template < class T > setOther() { // Function to change variable
// code to change variable type, or set type
}
void doSomethingWithOther() {
// do some processing for other, like call
// specific member function or something
(((other*)obj)->*SomeGenericMethod)()
}
}
int main(int argc, char **argv) {
Bar bObj;
generic<Foo> fObj;
fObj.setOther<Bar>();
fObj.doSomethingWithOther();
return 0;
}
我知道上面的代码由于很多原因无法编译,但我的问题更多是关于功能。有什么方法可以将模板参数存储为变量(或使用函数或其他东西),然后可以稍后用作类型说明符?如果没有标准方法,来自 SO 社区的任何想法可能会导致我想要的结果?
请不要使用 Boost 或其他 3rd 方库,我正尽量将其保持为“STL”(C99)。
我的另一个想法是使用默认特化:
template < class C, class T = void* > class generic {
public:
C obj;
T other;
// ... more code
}
但在那种情况下,假设我们有以下情况:
class Test1 {
public:
generic<Foo> *G1;
generic<Foo, Bar> *G2;
};
如果我以后想改变 G1 的类型来做一些其他的处理,我可以这样说:
G1 = new generic<Foo, Bar>(); // compile error, different types
但是,这会导致编译错误,因为指向的两种类型属于不同类型(G1 的类型为 generic< C >,另一个类型为 generic< C, T >,即使模板类 T 默认为 @987654328 @。
抱歉,这篇文章太长了,我试图用这段代码尽可能清楚地表达我的意图。另外,请随时纠正我在上面的任何陈述(长时间=我的大脑活动较少)
提前感谢您在此问题上的任何帮助。
编辑 1:
澄清一下,other 数据成员只是为了表明我希望该成员拥有一个类类型。这是因为我们的代码有其他类的成员调用实例化的成员函数。如果我要调用另一个类的成员函数,我会得到一个编译错误。
不幸的是,我无法使用任何 C++0x 功能,因为我们的嵌入式编译器较旧且不支持 0x 功能集。否则这将是显而易见的解决方案。
我本质上必须构建一个委托类型的系统,以便实例类可以从自身内部调用其他实例类的成员,并且被调用的成员函数将拥有内存空间并可以访问 this 指针
例子:
class Foo {
public:
Delegate other;
}
class Bar {
public:
void SomeFunction() {
std::cout << "hello from Bar::SomeFunction, data = " << data << std::endl;
}
int data;
}
int main() {
Foo F;
Bar B;
B.data = 10;
F.other = Delegate::attach<Bar>(&Bar::SomeFunction, &B);
// Delegate::attach is defined as
// template < class T > Delegate attach(void (T::*fnPtr)(void*), T *obj)
F.other();
}
在上面的示例中,Delegate 类的void operator()() 然后通过(*fnPtr)() 调用其他成员函数。如果以这种方式调用,该函数将无法访问其成员数据(不知道this 指针)。如果调用传递引用的对象(即(*fnPtr)(obj)),该函数现在可以访问成员数据。
我正在尝试通过指定一个通用的 class type 对象来解决这个问题,然后该对象可以来回转换,因为 Delegate other 可以附加到任何成员。
【问题讨论】:
-
other依赖什么来确定它是什么? -
¤ “请不要 Boost 或其他 3rd 方库”是弄巧成拙的。你不想再重新发明那个轮子,所以使用 boost::any 或 boost::variant (我忘了哪个是哪个)。或者使用该源代码作为起点,尽管您不太可能对其进行改进:使其不提升的修改只会降低质量。无论如何,你到底为什么想要这个?看起来确实您是在询问某个问题的设想解决方案,而不是询问那个问题。如果是这样,请询问问题。干杯&hth.,
-
“尽可能保持 STL”(我假设您的意思是 C++ 标准库):您知道标准受 Boost 及其作者的影响吗?
-
@pmr 这不是设计标准库或影响它的人,而是您必须重新分发(或希望收件人已经拥有)大型 boost 库 - 在学习并成功编译它之后,等等,对于某些人(包括我自己)来说,痛苦太多,收获却不够。
-
@Seth,我同意可移植性,这就是我试图避开第 3 方库的原因。虽然我不是想重新发明轮子,但公司要求我们的代码库尽可能地便携。它是我们一些嵌入式产品的通用 SDK,不幸的是,由于我们需要在一些平台上工作(奇怪的编译环境),因此需要大量的“重新发明轮子”。
标签: c++ class templates generics