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的链接不会像我想要的那样取代泛型动作.这是一个有效的担心吗?我读过许多让我感到不安的事情,但没有任何让我对目前情况发生的事情充满信心的事情. 解决方法
你有充分的理由担心:你的程序格式不正确,编译器甚至不需要告诉你! C 11标准第14.7.3 / 6段规定:
从实例化的角度来看,您的专业化必须是可见的,以便程序具有一致的行为.在您的情况下,它不是:您将其降级为其他翻译单元未包含的文件. 第14.7.3 / 7条标准非常明确地说明当你不这样做时会发生什么:
我猜最后一句话很清楚. 在这里,您应该做的是声明您在主模板的任何隐式实例化发生之前引入函数模板的显式特化的意图.为此,请执行以下操作: 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! 通过在主模板定义之后立即引入声明,您可以确保在主模板可见的任何地方,都会知道存在完整的专业化,从而使您免于自焚. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |