gpt4 book ai didi

c++ - 显式实例化模板类的显式实例化模板方法

转载 作者:行者123 更新时间:2023-12-03 07:11:52 28 4
gpt4 key购买 nike

我有一个带有模板参数 T 的类 A,它仅限于两种类型:T1 和 T2。因此,我为类型 T1 和 T2 显式实例化了类 A,这样 A 的功能可以在源文件中定义,并且不需要在每次包含 A.hpp 时都重新编译。
A.hpp:

template<typename T>
class A {
public:
void basicMethod();
};

template class A<T1>;
template class A<T2>;
A.cpp:
template<typename T>
void A<T>::basicMethod() {
// ...
}
但是,现在我想向 A 和 A 添加一个模板化方法,其中模板参数再次被限制为两种类型:S1 和 S2:
A.hpp:
template<typename T>
class A {
public:
void basicMethod();
template<typename S>
void advancedMethod();
};

template class A<T1>;
template class A<T2>;

// How to explicitly instantiate A::advancedMethod here?
A.cpp:
template<typename T>
void A<T>::basicMethod() {
// ...
}

template<typename T>
template<typename S>
void A<T>::advancedMethod() {
// ...
}
如何为 (T, S) = {T1, T2} x {S1, S2} 显式实例化 A ::advancedMethod ?根据我在网上找到的内容,我尝试将这样的内容添加到 A.hpp 的末尾:
template void A<T1>::advancedMethod(S1);
template void A<T1>::advancedMethod(S2);
template void A<T2>::advancedMethod(S1);
template void A<T2>::advancedMethod(S2);
但是,这根本不起作用。

最佳答案

类模板的成员函数模板的显式实例化定义
你几乎明白了。正确的语法是:

template void A<T1>::advancedMethod<S1>();
template void A<T1>::advancedMethod<S2>();
template void A<T2>::advancedMethod<S1>();
template void A<T2>::advancedMethod<S2>();
特别指出 advancedMethod()是在单个类型模板参数上参数化的函数模板,没有函数参数:您对函数模板的不同特化(对于定义它的类模板的不同特化)的显式实例化定义应该像显式实例化定义一样类模板,提供模板参数( <...> )以指定您希望显式实例化的特化。
最后, advancedMethod()对于显式实例化的每个特化,自然需要定义函数模板(通过主模板定义或显式特化);特别是( cppreference):

If a function template, variable template, member function template, or member function or static data member of a class template is explicitly instantiated with an explicit instantiation definition, the template definition must be present in the same translation unit.



将模板函数(/class 模板成员函数)的定义与其声明分开: -timl.hpp图案
作为上述要求的结果,在提供显式实例化定义时,您通常将它们放在相关模板化实体的定义之后,在源文件中,其中典型的用例是模板化实体的公共(public) API 的用户应该无权访问定义(如您的示例中所示)。这是必不可少的,因为根据 [temp.spec]/5,您可能不会在不同的翻译单元上显式地两次实例化相同的特化。 :

For a given set of template arguments,

  • an explicit instantiation definition shall appear at most once in a program,
  • [...]

An implementation is not required to diagnose a violation of this rule.


因此,如果您将显式实例化放在头文件中,然后将头文件包含在多个源文件中,那么您的程序将是格式错误的 NDR。
// a.hpp
template<typename T>
class A {
public:
void basicMethod();
template<typename S>
void advancedMethod();
};

// a-timpl.hpp
#include "a.hpp"

template<typename T>
void A<T>::basicMethod() {
// ...
}

template<typename T>
template<typename S>
void A<T>::advancedMethod() {
// ...
}

// a.cpp
#include "a-timpl.hpp"
#include "t1.hpp"
#include "t2.hpp"
#include "s1.hpp"
#include "s2.hpp"

// Explicit instantiation definitions for
// production intent.
template class A<T1>;
template class A<T2>;

template void A<T1>::advancedMethod<S1>();
template void A<T1>::advancedMethod<S2>();
template void A<T2>::advancedMethod<S1>();
template void A<T2>::advancedMethod<S2>();
对于测试,您同样包括 -timpl.hpp头文件而不是主 header (主 header 用于公共(public) API 公开),这样您就可以使用模板定义来显式实例化测试中使用的特化:
// a_test.cpp
#include "a-timpl.hpp"
#include "t1_mock.h"
#include "t2_mock.h"
#include "s1_mock.h"
#include "s2_mock.h"

// Explicit instantiation definitions for
// test intent.
template class A<T1Mock>;
template class A<T2Mock>;

template void A<T1Mock>::advancedMethod<S1Mock>();
template void A<T1Mock>::advancedMethod<S2Mock>();
template void A<T2Mock>::advancedMethod<S1Mock>();
template void A<T2Mock>::advancedMethod<S2Mock>();

关于c++ - 显式实例化模板类的显式实例化模板方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64910370/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com