C ++ 11:显式实例化声明与显式实例化定义 [英] C++11: Explicit instantiation declaration vs. explicit instantiation definition

查看:154
本文介绍了C ++ 11:显式实例化声明与显式实例化定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++ 03的显式模板的实例化定义和C ++ 11的显式模板的实例化声明有什么区别?



我的意思是为什么实例化定义不足以阻止编译器为其他类型生成实现?在下面的示例中出了什么问题:想象我将模板声明和定义分为两个单独的文件:



Ah

  #pragma一次

template< typename T>
A类
{
公共:
A(T t);

私人:
T _t;
};

A.cpp

  #include Ah 

template< typename T>
A< T> :: A(T t):_t(t){}

模板类A< int> ;; //显式实例

main.cpp

  #include Ah 

int main()
{
A< int> a(5); //好的,编译器会生成头文件
//链接程序链接A.cpp文件中的实现

// A< float> b(3.14f); //链接器错误,如预期的那样
}

上面的示例中是否有任何编译时间开销?如果我理解正确,在这种情况下,请在单独的* .cpp文件中使用显式实例化定义(以及模板的实现),使编译器无法隐式实例化任何其他类型的模板。因此,为什么要为显式实例化声明使用单独的语法?



如果我已经使用显式实例化在A.cpp文件中隐藏了实现,则显式实例化声明如何加快编译时间。定义,并阻止编译器为其他类型生成主体。 显式实例化声明是否与显式实例化定义相关,我是说我应该同时使用它们,还是这些是完全独立的功能(例如,仅在未使用显式实例化定义的情况下才可以使用显式实例化声明)? / p>

我想对了,如果没有其他翻译单元使用给定类型实例化模板,则显式实例化定义仅会触发错误?

解决方案

当您在文件 A.cpp 中放置显式实例化定义时,编译器应该如何处理?在编译 main.cpp 时知道吗?答案是它不能这样做,因此它仍将实例化 main.cpp 中使用的模板,并且在您的情况下,使用显式实例化定义是无用的,并且不会



显式实例化的声明对编译器说:不要打扰实例化此模板,我自己在程序中的其他地方也可以这样做,并且



显式实例化必须只在一个文件中定义一次,但是可以在不同文件中多次声明。这并不是模板所独有的,在C和C ++中,相同的规则适用于(非内联)函数:您可以在不同的文件中多次声明它们(通常通过将声明放在标头中),然后必须准确定义函数



因此,要使您的示例正常运行,应在 Ah 中添加一个声明:

 外部模板类A< int> ;; //显式实例化声明


What is the difference between the C++03's explicit template's instantiation definition and C++11's explicit template's instantiation declaration ?

What I mean is why the instantiation definition is not enough to prevent the compiler from generating implementation for other types ? What is wrong in the below example: imagine I split up the template declaration and definition into two separate files:

A.h

#pragma once

template<typename T>
class A
{
public:
    A(T t);

private:
    T _t;
};

A.cpp

#include "A.h"

template<typename T>
A<T>::A(T t) : _t(t) {}

template class A<int>; // explicit instantiation

main.cpp

#include "A.h"

int main()
{
    A<int> a(5); // fine, compiler generates header file,
                 // linker links with implementation from A.cpp file

    // A<float> b(3.14f); // linker error, as expected
}

Is there any compilation time overhead in example above? If I understand correctly, in such case, using explicit instantiation definition in a separate *.cpp file (along with template's implementation) I make the compiler to be unable to implicitly instantiate the template with any other types. As such, why there is a separate syntax for explicit instantiation declaration ?

How can explicit instantiation declaration speed up compilation time, if I had ALREADY hidden the implementation in A.cpp file using explicit instantiation definition, and prevented compiler from generating body for other types. Is the "explicit instantiation declaration" somehow related to "explicit instantiation definition", I mean should I use them both, or these are completely separate features (e.g. explicit instantiation declaration can be used only if explicit instantiation definition has not been used) ?

Am I thinking right, that the explicit instantiation definition is only to trigger error in case no other translation unit instantiates the template using given type?

解决方案

When you put an explicit instantiation definition in the file A.cpp, how is the compiler supposed to know it's there when compiling main.cpp? The answer is that it can't, so it would still instantiate the templates used in main.cpp, and in your case using the explicit instantiation definition is useless and doesn't help.

A declaration of an explicit instantiation says to the compiler "do not bother instantiating this template, I will do so myself, somewhere else in the program", and the definition is what fulfils that promise.

The explicit instantiation must be defined exactly once, in only one file, but it can be declared multiple times in different files. This is nothing unique to templates, in C and C++ the same rules apply to (non-inline) functions: you can declare them multiple times in different files (usually by putting the declaration in a header) and then you must define the function exactly once, in one file.

So to make your example work properly you should add a declaration in A.h:

extern template class A<int>; // explicit instantiation declaration

这篇关于C ++ 11:显式实例化声明与显式实例化定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆