c – 当链接器可以使用显式特化时,所有编译器是否忽略生成的模板代码?

前端之家收集整理的这篇文章主要介绍了c – 当链接器可以使用显式特化时,所有编译器是否忽略生成的模板代码?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我最近遇到一种情况,同时专门化模板让我感到不安:

foo.h中:

template <class T>
void foo() {
  std::cout << "This is the generic foo" << std::endl;
}

foo.cc:

#include "foo.h"
template <>
void foo<int>() {
  std::cout << "This is foo<int>" << std::endl;
}

main.cc:

#include "foo.h"

int main() {
  foo<int>();
}

所以.我编译如下:

g++ -c main.cc
g++ -c foo.cc
g++ -o main main.o foo.o

输出是“This is foo< int>”.我喜欢这个输出.但我担心我所观察到的可能是gcc独有的(我无法访问其他编译器,所以我无法检查).

这就是我认为gcc正在做的事情:当编译main.cc时,我希望它为foo调用发出通用代码,因为它不知道foo.cc中的特殊化.但是通过与foo.o链接,它使用了特化,因为它具有相同的签名.

但这是不是值得依靠?我担心其他编译器(或者甚至是不同版本的gcc?)在发出模板代码时可能会破坏它们的签名,这种方式与foo.o的链接不会像我想要的那样取代泛型动作.这是一个有效的担心吗?我读过许多让我感到不安的事情,但没有任何让我对目前情况发生的事情充满信心的事情.

解决方法

I’m worried that what I’m observing might be unique to gcc (I don’t have access to other compilers so I can’t check).

你有充分的理由担心:你的程序格式不正确,编译器甚至不需要告诉你!

C 11标准第14.7.3 / 6段规定:

If a template,a member template or a member of a class template is explicitly specialized then that specialization
shall be declared before the first use of that specialization that would cause an implicit instantiation
to take place,in every translation unit in which such a use occurs; no diagnostic is required.
If the program
does not provide a definition for an explicit specialization and either the specialization is used in a way
that would cause an implicit instantiation to take place or the member is a virtual member function,the
program is ill-formed,no diagnostic required
. An implicit instantiation is never generated for an explicit
specialization that is declared but not defined

从实例化的角度来看,您的专业化必须是可见的,以便程序具有一致的行为.在您的情况下,它不是:您将其降级为其他翻译单元未包含的文件.

第14.7.3 / 7条标准非常明确地说明当你不这样做时会发生什么:

The placement of explicit specialization declarations for function templates,class templates,member functions
of class templates,[…],can affect whether a program is
well-formed according to the relative positioning of the explicit specialization declarations and their points of
instantiation in the translation unit as specified above and below. When writing a specialization,be careful
about its location; or to make it compile will be such a trial as to kindle its self-immolation.

我猜最后一句话很清楚.

在这里,您应该做的是声明您在主模板的任何隐式实例化发生之前引入函数模板的显式特化的意图.为此,请执行以下操作:

foo.h中

template <class T>
void foo() {
   std::cout << "This is the generic foo" << std::endl;
}

template <> void foo<int>(); // Introduce a declaration of your
                             // explicit specialization right
                             // after you defined the primary
                             // template!

通过在主模板定义之后立即引入声明,您可以确保在主模板可见的任何地方,都会知道存在完整的专业化,从而使您免于自焚.

猜你在找的C&C++相关文章