c – 在获取地址时隐式实例化函数模板
注意:我已经看过
here了,我认为答案是对的.
在获取地址时,管理函数隐式实例化的规则是什么? n3242的14.7.1 / 9说:
现在,当然不需要有一个函数定义来获取它的地址.我们可以获取前向声明函数的地址,并将它们定义在不同的转换单元中. 既然如此,我不知道什么时候需要它.然而,编译器似乎有自己的想法.在GCC和VC上进行测试,这里有几个例子: template <typename T> void CallBanana() { T::Banana(); } template <typename T> void CallUnimpl(); template <typename T> struct S { static void CallBanana() { T::Banana(); } static void CallOrange() { T::Orange(); } static void CallUnimpl(); }; struct B { static void Banana() {} }; int main() { (void)(&CallBanana<void>); // 1 (void)(&CallUnimpl<void>); // 2 (void)(&S<void>::CallBanana); // 3 (void)(&S<void>::CallOrange); // 4 (void)(&S<void>::CallUnimpl); // 5 (void)(&S<B>::CallBanana); // 6 } 这些应该一次评论一次,以查看效果. GCC 4.7 tested here会抱怨1,3和4.因此,如果它们存在,它将实例化所有定义. VC 2010(没有在线测试,抱歉)实例化3和4,但没有实例化1. Clang 3.0 tested here与VC 2010具有相同的行为. 没有编译器抱怨2或5,我期望.如果我实际使用了那些指针,我希望它无法链接. 在所有编译器上,6个编译器.我期待这一点,但它的目的是为了表明整个类模板没有实例化(正如在其他问题的答案中所声称的那样),因为我采用了单个函数的地址.如果整个模板被实例化,那么S :: CallOrange不应该编译,因为B不包含Orange函数. 所以我想知道是否有人对于正确的行为应该是什么有明确的答案.该标准似乎声称不应该实例化任何函数,但是在某些情况下,三个流行的编译器会实例化,但它们之间也会有所不同. 解决方法
如果采用其地址(在评估的上下文中)所需的函数定义.
当然,定义可以在单独的翻译单元中给出,但这并不会改变需要定义的事实. 如果只需要一个成员函数,那并不意味着其他成员函数也被实例化. 如果函数模板未定义,则无法隐式实例化.然后必须在另一个翻译单元中明确地实例化它.不允许依赖于另一个翻译单元中的隐式实例化(但不需要诊断). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |