Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何显式实例化基模板类?_C++_Templates_Inheritance_Explicit Instantiation - Fatal编程技术网

C++ 如何显式实例化基模板类?

C++ 如何显式实例化基模板类?,c++,templates,inheritance,explicit-instantiation,C++,Templates,Inheritance,Explicit Instantiation,这个问题考虑的是模板类的显式实例化 考虑从另一个模板类a派生的模板类B。我想显式实例化B,因为它的方法是从动态链接调用的,所以这些方法必须实例化,尽管它们不是在代码本身中调用的。当然,还将调用从A继承的方法,因此它们也必须实例化 看起来,C++在显式地设置模板类时不会初始化基类,正如在这个问题中所提出的: 例如: 模板 类{void foo(){…}}; 模板 B类:公共A{} 模板类别B;//这不会实例化A::foo()!!! 当然,我还需要实例化所有基类。但是,我不想给客户机代码带来负担,

这个问题考虑的是模板类的显式实例化

考虑从另一个模板类
a
派生的模板类
B
。我想显式实例化
B
,因为它的方法是从动态链接调用的,所以这些方法必须实例化,尽管它们不是在代码本身中调用的。当然,还将调用从
A
继承的方法,因此它们也必须实例化

<>看起来,C++在显式地设置模板类时不会初始化基类,正如在这个问题中所提出的: 例如:

模板
类{void foo(){…}};
模板
B类:公共A{}
模板类别B;//这不会实例化A::foo()!!!
当然,我还需要实例化所有基类。但是,我不想给客户机代码带来负担,因为类的层次结构可能很深。考虑包含10个或更多模板类的类层次结构。不应敦促客户机编写10个显式模板实例。这不仅仅是大量的写作;当我对类层次结构进行更改时,它也会中断

相反,我希望以某种方式实现,无论何时实例化
B
,它的所有基类都是如此。我尝试简单地在B中实例化基类,如下所示:

template<typename T>
class B : public A<T> {
    template class A<T>; // Does not compile!
}
模板
B类:公共A{
模板类A;//未编译!
}

但这并不适用于编译。是否有其他方法可以实现这一点?

可能不优雅,但至少可行:提供一个宏来实例化模板,并要求用户使用宏来代替手动实例化:

// in A.hpp
#define INSTANTIATE_A(T) template class A<T>;

// in B.hpp
#define INSTANTIATE_B(T) \
    INSTANTIATE_A(T)     \
    template class B<T>;
更新:

第二种解决方案的替代方案:获取所有成员的函数指针并将其保存到临时变量:

template<typename T>
class A
{
    void foo() {...}
protected:
    void instantiate() { void (A::*p)() = &A::foo; }
};

template<typename T>
class B : public A<T>
{
    void bar() {...}
protected:
    void instantiate() { A<T>::instantiate(); void (B::*p)() = &B::foo; }
};
模板
甲级
{
void foo(){…}
受保护的:
void实例化(){void(A::*p)(=&A::foo;}
};
模板
B类:公共A
{
无效条(){…}
受保护的:
void instantiate(){A::instantiate();void(B::*p)(=&B::foo;}
};

第二种解决方案的问题是,某些方法具有较大的签名,并且不容易生成值以提供给这些方法。第一种方法可以工作,但确实很难看:(.添加了第二种解决方案的变体,尽管这几乎是冗长的,并且不是真正需要的:其思想是
instantiate()
从未真正执行过。好吧,这更可行。但是,接口仍然很大,所以枚举所有方法比枚举所有基类要困难得多。我希望有其他方法可以解决这个问题,不过还是要感谢您的回答。
template<typename T>
class A
{
    void foo() {...}
protected:
    void instantiate() { foo(); }
};

template<typename T>
class B : public A<T>
{
    void bar() {...}
protected:
    void instantiate() { A<T>::instantiate(); bar(); }
};

template class B<int>; // Now works as expected
template<typename T>
class A
{
    void foo() {...}
protected:
    void instantiate() { void (A::*p)() = &A::foo; }
};

template<typename T>
class B : public A<T>
{
    void bar() {...}
protected:
    void instantiate() { A<T>::instantiate(); void (B::*p)() = &B::foo; }
};