我可以将“外部模板”放入头文件吗? [英] Can I put `extern template` into a header file?

查看:80
本文介绍了我可以将“外部模板”放入头文件吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否将extern模板放在头文件中,然后在单位编译文件中使显式模板实例化有效吗?



例如在 g ++ ,这样做是为了避免两次两次<< c $ c> nothing< int> 的实例化吗?为什么没有人这样写,而是喜欢在每个.cpp文件中复制pase extern模板行?



A.hpp:

  #ifndef HEADERC_A 
#define HEADERC_A

模板<类型名称T>不构造任何结构{};
extern模板struct none< int> ;;

#endif

A.cpp:

  #include A.hpp 

模板struct none< int>

main.cpp:

  #include A.hpp 
#include< iostream>

int main()
{
none< int> n;
返回0;
}


解决方案

如前所述,这是一个完全有效的用例,如果它适合您的编程模型,则应使用它。但是买家要当心:



有几个原因导致外部模板通常不在头文件中声明,然后在cpp文件中显式实例化。



用于实现模板类/功能的非常常见的模型是将定义放在头文件中,并将实现放在 inl或其他命名文件中。但是,请将该文件包含在头文件的底部。有大量的代码使用这种方法来解决模板/标题/实现分离问题。在实现的顶部放置外部可使代码更易于阅读和维护,尤其是涉及多个类时。这是一个示例:



A.hpp

  #pragma一旦
template<类型名称T>什么也没有构造{
void donothing(T input); //最快的功能在
左右};
#include A.inl

A.inl

  //不包含A.hpp 
外部模板struct none< int> ;; //节省时间和空间
template< typename T>什么都没有< T> :: donothing {return; }

Instance.h

  #include A.hpp 
模板struct none< int> ;; //编译器现在会生成代码

但是所有这些都有一个隐藏的警告...



如果按照您的建议实施了此操作,那么当另一个人出现并想要时会发生什么情况 c $ c> nothing< float>虚无

编译器将看到头文件,但从未找到float的实现。因此,它可能编译得很好,但是在链接时会有无法解析的符号。
因此,他们尝试了以下操作:

  template struct none  
none< float>虚无

错误!现在,编译器找不到实现,而您得到的只是更多错误。



现在,您可以返回A.cpp文件并添加另一个float实例...您能说维护,头痛,腕管噩梦吗?使用常用的解决方案,您可以吃到蛋糕。 (大部分)



现在您可能在想为什么还要烦扰外部人呢?因为正如您的帖子所暗示的那样,有一个典型的用例,在大多数情况下,无将与int模板类型一起使用。在潜在的数百个文件中发生这种情况会导致严重的编译时间和代码大小后果。



标准委员会为什么不对这种混乱做些什么?他们做到了!他们添加了extern模板!公平地说,事后解决这个问题很困难。


Is putting an extern template in a header file and then do the explicit template instantiation in a unit compilation file valid ?

For example in the compiling example for g++, is this working to avoid the instancation of nothing<int> twice ? Why doesn't anybody write it like this and prefer to copy pase the extern template line in each .cpp file ?

A.hpp:

#ifndef HEADERC_A
#define HEADERC_A

template< typename T > struct nothing {};
extern template struct nothing<int>;

#endif

A.cpp:

#include "A.hpp"

template struct nothing<int>;

main.cpp:

#include "A.hpp"
#include <iostream>

int main()
{
    nothing<int> n;
    return 0;
}

解决方案

As previously stated this is a perfectly valid use case and if it fits your programming model then you should use it. But buyer beware:

There are several reasons why extern templates are not commonly declared in header files and then explicitly instantiated in the cpp files.

A very common model for implementing template classes/functions is to place the definitions in the header file and the implementation in an "inl" or other named file. But then include that file at the bottom of the header file. There are reams of code that use this approach to resolving the template/header/implementation separation problem. Putting an "extern" at the top of the implementation makes the code much easier to read and maintain, especially when multiple classes get involved. Heres an example:

A.hpp

#pragma once
template< typename T > struct nothing {
  void donothing(T input); // fastest func around
};
#include "A.inl"

A.inl

// does NOT include A.hpp
extern template struct nothing<int>; // save time and space
template<typename T> nothing<T>::donothing { return; }

Instance.h

#include "A.hpp"
template struct nothing<int>; // compiler generates code now

But there is a hidden caveat in all this...

If this gets implemented as you suggest then what happens when another person comes along and wants:

nothing<float> mynothing;

The compiler will see the header file but never find an implementation for float. So it may compile just fine, but at link time there will be unresolvable symbols. So they try this:

template struct nothing<float>;
nothing<float> mynothing;

WRONG! Now the compiler can't find the implementation and all you get is MORE errors.

Now you could go back to your A.cpp file and add another instance for float...can you say maintenance, headache, carpal tunnel nightmare? With the commonly used solution you get to have your cake and eat it to. (mostly)

Now you may be thinking why even bother with the extern? Because as your post implies there is a typical use case where most of the time "nothing" will be used with an int template type. Having this occur in potentially hundreds of files can lead to serious compile time and code size ramifications.

Why doesn't the standards committee do something about this mess? They did! They added extern templates! In all fairness it is a difficult issue to resolve after the fact.

这篇关于我可以将“外部模板”放入头文件吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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