对C ++ 0x标准中export关键字的最佳解释是什么? [英] What is the best explanation for the export keyword in the C++0x standard?

查看:165
本文介绍了对C ++ 0x标准中export关键字的最佳解释是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道在原来的C ++ 0x标准中有一个功能 export



但是我找不到此功能的说明或解释。它应该做什么?虽然标准C ++没有这样的要求,但是一些编译器要求所有的函数模板都需要这样的函数模板:在其使用的每个翻译单元中是可用的。实际上,对于那些编译器,模板函数的主体必须在头文件中可用。重复:这意味着这些编译器不允许在非头文件(如.cpp文件)中定义它们。要澄清,在C ++ ese中,这意味着:

  // xyz.h 
的ORIGINAL版本< typename T>
struct xyz
{
xyz();
〜xyz();
};

不会满足ctor和dtors的定义:

  // xyz.cpp的ORIGINAL版本
#includexyz.h

template< typename T>
xyz< T> :: xyz(){}

template< typename T>
xyz< T> ::〜xyz(){}

/ p>

  // main.cpp 
#includexyz.h

int main )
{
xyz< int> xyzint;

return 0;
}

会产生错误。例如,使用Comeau C ++,您将获得:


  C:\export> como xyz .cpp main.cpp 
C ++'xyz.cpp ...
Comeau C / C ++ 4.3.4.1(2004年5月29日23:08:11)for MS_WINDOWS_x86
版权所有1988-2004 Comeau计算。版权所有。
模式:非严格警告微软C ++

C ++的main.cpp ...
Comeau C / C ++ 4.3.4.1(2004年5月29日23:08:11) for MS_WINDOWS_x86
版权所有1988-2004 Comeau Computing。版权所有。
MODE:非严格警告微软C ++

main.obj:error LNK2001:未解析的外部符号xyz< T1> ::〜xyz< int>()[with T1 = int]
main.obj:error LNK2019:未解析的外部符号xyz< T1> :: xyz< int>()[with T1 = int]在函数_main中引用
aout.exe:致命错误LNK1120:2 unresolved externals


,因为xyz中没有使用ctor或dtor。 cpp,因此,没有实例化需要从那里发生。



其中一个方法是明确请求实例化 xyz ,在 xyz< int> 的示例中。在强力的努力,这可以添加到xyz.cpp通过在它的末尾添加这行:

 模板xyz< ; int> ;; 

请求(所有) xyz< int> 被实例化。这是在错误的地方,虽然,因为这意味着每次一个新的xyz类型带来的实现文件xyz.cpp必须修改。避免该文件的一个较少侵入的方法是创建另一个:

  // xyztir.cpp 
#includexyz .cpp// .cpp文件!!!,不是.h文件!

template xyz< int> ;;

这还是有些痛苦,因为它仍然需要一个手动干预每次一个新的xyz。在一个不平凡的程序中,这可能是一个不合理的维护需求。



因此,另一种方法是使用 #includexyz。 cpp到xyz.h结尾:

  // xyz.h 

// ...以前的内容xyz.h ...

#includexyz.cpp

你当然可以把xyz.cpp的内容带到(剪切和粘贴)xyz.h的结尾,从而摆脱xyz.cpp;这是文件组织的问题,并且最终预处理的结果将是相同的,因为ctor和dtor主体将在标题中,并且因此被带入任何编译请求,因为将使用相应的标题。无论如何,这有副作用,现在每个模板都在您的头文件。它可能会减慢编译,并可能导致代码膨胀。接近后者的一种方法是声明有问题的函数,在这种情况下,ctor和dtor,作为内联,所以这将需要你在运行示例中修改xyz.cpp。



另外,一些编译器还要求一些函数在类中内联定义,而不是在一个类之外,因此上述设置需要在这些编译器的情况下进一步调整。注意,这是一个编译器问题,而不是标准C ++,所以不是所有的编译器都需要这个。例如,Comeau C ++不,也不应该。请查看 http://www.comeaucomputing.com/4.0/docs/userman/ati.html有关我们当前设置的详细信息。简而言之,Comeau C ++支持许多模型,包括接近导出关键字的意图(作为扩展),甚至支持导出本身。



最后,请注意,C ++ export关键字旨在缓解原始问题。然而,目前Comeau C ++是唯一的编译器,正在被宣传支持导出。请参见 http://www.comeaucomputing.com/4.0/docs/userman/export.html http://www.comeaucomputing.com/4.3.0/minor/win95+/43stuff.txt 了解详情。希望随着其他编译器符合标准C ++,这种情况将改变。在上面的示例中,使用export意味着返回产生链接器错误的原始代码,并进行更改:使用export关键字在xyz.h中声明模板:

  // xyz.h 

export
// ... xyz.h ... ORIGINAL的内容...

xyz.cpp中的ctor和dtor将只通过#includeing xyz.h导出,因此,在这种情况下,您不需要xyztir.cpp,也不需要在xyz.cpp结束时的实例化请求,并且您不需要手动将ctor或dtor引入到xyz.h中。使用之前显示的命令行,编译器可能会自动为您执行此操作。


I know that in the original C++0x standard there was a feature called export.

But I can't find a description or explanation of this feature. What is it supposed to do? Also: which compiler is supporting it?

解决方案

Although Standard C++ has no such requirement, some compilers require that all function templates need to be made available in every translation unit that it is used in. In effect, for those compilers, the bodies of template functions must be made available in a header file. To repeat: that means those compilers won't allow them to be defined in non-header files such as .cpp files. To clarify, in C++ese this means that this:

// ORIGINAL version of xyz.h
template <typename T>
struct xyz
 {
    xyz();
    ~xyz();
 };

would NOT be satisfied with these definitions of the ctor and dtors:

// ORIGINAL version of xyz.cpp
#include "xyz.h"

template <typename T>
xyz<T>::xyz() {}

template <typename T>
xyz<T>::~xyz() {}

because using it:

// main.cpp
#include "xyz.h"

int main()
 {
    xyz<int> xyzint;

    return 0;
 }

will produce an error. For instance, with Comeau C++ you'd get:

C:\export>como xyz.cpp main.cpp
C++'ing xyz.cpp...
Comeau C/C++ 4.3.4.1 (May 29 2004 23:08:11) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing.  All rights reserved.
MODE:non-strict warnings microsoft C++

C++'ing main.cpp...
Comeau C/C++ 4.3.4.1 (May 29 2004 23:08:11) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing.  All rights reserved.
MODE:non-strict warnings microsoft C++

main.obj : error LNK2001: unresolved external symbol xyz<T1>::~xyz<int>() [with T1=int]
main.obj : error LNK2019: unresolved external symbol xyz<T1>::xyz<int>() [with T1=int] referenced in function _main
aout.exe : fatal error LNK1120: 2 unresolved externals

because there is no use of the ctor or dtor within xyz.cpp, therefore, there is no instantiations that needs to occur from there. For better or worse, this is how templates work.

One way around this is to explicitly request the instantiation of xyz, in this example of xyz<int>. In a brute force effort, this could be added to xyz.cpp by adding this line at the end of it:

template xyz<int>;

which requests that (all of) xyz<int> be instantiated. That's kind of in the wrong place though, since it means that everytime a new xyz type is brought about that the implementation file xyz.cpp must be modified. A less intrusive way to avoid that file is to create another:

// xyztir.cpp
#include "xyz.cpp" // .cpp file!!!, not .h file!!

template xyz<int>;

This is still somewhat painful because it still requires a manual intervention everytime a new xyz is brought forth. In a non-trivial program this could be an unreasonable maintenance demand.

So instead, another way to approach this is to #include "xyz.cpp" into the end of xyz.h:

// xyz.h

// ... previous content of xyz.h ...

#include "xyz.cpp"

You could of course literally bring (cut and paste it) the contents of xyz.cpp to the end of xyz.h, hence getting rid of xyz.cpp; it's a question of file organization and in the end the results of preprocessing will be the same, in that the ctor and dtor bodies will be in the header, and hence brought into any compilation request, since that would be using the respective header. Either way, this has the side-effect that now every template is in your header file. It could slow compilation, and it could result in code bloat. One way to approach the latter is to declare the functions in question, in this case the ctor and dtor, as inline, so this would require you to modify xyz.cpp in the running example.

As an aside, some compilers also require that some functions be defined inline inside a class, and not outside of one, so the setup above would need to be tweaked further in the case of those compilers. Note that this is a compiler issue, not one of Standard C++, so not all compilers require this. For instance, Comeau C++ does not, nor should it. Check out http://www.comeaucomputing.com/4.0/docs/userman/ati.html for details on our current setup. In short, Comeau C++ supports many models, including one which comes close to what the export keyword's intentions are (as an extension) as well as even supporting export itself.

Lastly, note that the C++ export keyword is intended to alleviate the original question. However, currently Comeau C++ is the only compiler which is being publicized to support export. See http://www.comeaucomputing.com/4.0/docs/userman/export.html and http://www.comeaucomputing.com/4.3.0/minor/win95+/43stuff.txt for some details. Hopefully as other compilers reach compliance with Standard C++, this situation will change. In the example above, using export means returning to the original code which produced the linker errors, and making a change: declare the template in xyz.h with the export keyword:

// xyz.h

export
// ... ORIGINAL contents of xyz.h ...

The ctor and dtor in xyz.cpp will be exported simply by virtue of #includeing xyz.h, which it already does. So, in this case you don't need xyztir.cpp, nor the instantiation request at the end of xyz.cpp, and you don't need the ctor or dtor manually brought into xyz.h. With the command line shown earlier, it's possible that the compiler will do it all for you automatically.

这篇关于对C ++ 0x标准中export关键字的最佳解释是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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