简体   繁体   English

显式实例化模板类的显式实例化模板方法

[英]Explicitly instantiate template method of explicitly instantiated template class

I have a class A with template argument T, which is limited to two types: T1 and T2.我有一个带有模板参数 T 的类 A,它仅限于两种类型:T1 和 T2。 Because of this, I explicitly instantiated class A for types T1 and T2 such that A's functionality can be defined in a source file and doesn't need to be recompiled every time A.hpp is included.因此,我为类型 T1 和 T2 显式实例化了类 A,这样 A 的功能就可以在源文件中定义,并且不需要在每次包含 A.hpp 时重新编译。

A.hpp: A.hpp:

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

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

A.cpp: A.cpp:

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

However, now I want to add a templated method to both A<T1> and A<T2> where the template argument is limited to two types again: S1 and S2:但是,现在我想向 A<T1> 和 A<T2> 添加一个模板化方法,其中模板参数再次限制为两种类型:S1 和 S2:

A.hpp: 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: A.cpp:

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

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

How do I explicitly instantiate A<T>::advancedMethod<S> for (T, S) = {T1, T2} x {S1, S2}?如何为 (T, S) = {T1, T2} x {S1, S2} 显式实例化 A<T>::advancedMethod<S>? Based on what I found online, I tried adding things like this to the end of A.hpp:根据我在网上找到的内容,我尝试在 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);

However, this did not work at all.然而,这根本不起作用。

Explicit instantiation definitions for member function templates of class templates类模板的成员函数模板的显式实例化定义

You nearly got it.你差点就明白了。 The correct syntax is:正确的语法是:

template void A<T1>::advancedMethod<S1>();
template void A<T1>::advancedMethod<S2>();
template void A<T2>::advancedMethod<S1>();
template void A<T2>::advancedMethod<S2>();

Specifically noting that advancedMethod() is a function template parameterized over a single type template parameter, with no function parameters: your explicit instantiation definitions for different specialization of the function template (for different specializations of the class template in which it is defined) should, like the explicit instantiation definitions for the class template, provide the template arguments ( <...> ) as to specify the specializations you wish to explicitly instantiate.特别要注意的是, advancedMethod()是一个通过单个类型模板参数参数化的函数模板,没有函数参数:函数模板的不同专业化(定义它的类模板的不同专业化)的显式实例化定义应该,像类模板的显式实例化定义一样,提供模板参数 ( <...> ) 以指定您希望显式实例化的特化。

Finally, the advancedMethod() function template naturally needs to be defined (either via a primary template definition or in an explicit specialization) for each specialization which is explicitly instantiated;最后, advancedMethod()函数模板自然需要为每个显式实例化的特化定义(通过主模板定义或在显式特化中); particularly ( cppreference ):特别是( 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.如果使用显式实例化定义显式实例化类模板的函数模板、变量模板、成员函数模板或成员函数或静态数据成员,则模板定义必须存在于同一翻译单元中。


Separating definitions of template functions (/class template member functions) from their declarations: the -timl.hpp pattern将模板函数(/class 模板成员函数)的定义与其声明-timl.hpp-timl.hpp模式

As an effect of the requirement above, when supplying explicit instantiation definitions, you typically place these after the definitions of the related templated entities, in a source file , where the typical use case is that a user of the public API of the templated entity should not have access to the definitions (as in your example).作为上述要求的结果,当提供显式实例化定义时,您通常将这些定义放在相关模板化实体的定义之后在源文件中,其中典型的用例是模板化实体的公共 API 的用户应该无法访问定义(如您的示例)。 This is essential as you may not explicitly instantiate the same specialization twice over different translation units, as per As per [temp.spec]/5 :这是必不可少的,因为您可能不会根据[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.不需要实现来诊断违反此规则的行为

Thus, if you place the explicit instantiations in the header, and then include the header in more than one source file, your program will be ill-formed, NDR.因此,如果您将显式实例化放在头文件中,然后将头文件包含在多个源文件中,您的程序将是格式错误的,即 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>();

For test, you similarly include the -timpl.hpp header file rather than the main header (the main header is for the public API exposure), such that you may use the templated definitions to explicit instantiate specializations used in test:对于测试,您类似地包含-timpl.hpp头文件而不是主头文件(主头用于公共 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>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在模板类中显式实例化模板函数? - How to explicitly instantiate the template function in the template class? 显式实例化类模板中的自动构造函数 - Automatic constructor in explicitly instantiated class template 从 dll 导入显式实例化的模板 class - Importing explicitly instantiated template class from dll 除非显式专用,否则未实例化模板类的静态成员? - Static member of template class not instantiated unless explicitly specialized? 如何在Visual Studio中导出从显式实例化模板派生的类? - How to export a class derived from an explicitly instantiated template in Visual Studio? 如何使用完全专用的成员正确显式实例化模板类? - How to properly explicitly instantiate a template class with fully-specialized members? 如何在C ++中使用默认模板参数显式实例化类? - How to explicitly instantiate class with default template arguments in C++? 将显式实例化的函数模板与转换匹配 - Matching explicitly instantiated function template with conversion 未定义的对显式实例化模板函数的引用 - Undefined reference to explicitly instantiated template function 显式实例化模板方法中的编译错误 - Compilation error in explicitly instantiated template methods
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM