采用地址时,模板类型(类/函数)的实例化规则是什么? [英] What are the rules around instantiation of template types (class/function) when taking an address?

查看:198
本文介绍了采用地址时,模板类型(类/函数)的实例化规则是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在回答问题时,我遇到了这个问题

In answering this question, I came across this difference in behaviour with respect to template instantiation.

最初有一个函数模板

template <typename T> void my_callback(void* data) { … }



现在有些东西需要这个地址 - code> void * ,所以显而易见的方法是

Now something requires the address of this - specifically a void*, so the obvious approach is

bar(reinterpret_cast<void*>(&my_callback<int>));

但是,对于编译器版本pre gcc 4.5,这将失败与一个不足够的上下文...错误。好 - 修正是强制第一个 - 强制实例化,即:

However, with compiler versions pre gcc 4.5, this fails with a not-enough context... error. Fine - so the fix is to "cast" first - which forces instantiation, i.e:

void (*callback)(void*) = my_callback<int>;
bar(reinterpret_cast<void*>(callback));

这很好。

现在第二种情况,而不是一个自由函数,它是一个类模板的静态成员,即

Now the second scenario, rather than being a free function, it's a static member of a class template, i.e.

template <typename T>
struct foo
{
  static void my_callback(void* data) {
    T& x = *static_cast<T*>(data);
    std:: cout << "Call[T] with " << x << std::endl;
  }
};

现在,原来的 reinterpret_cast

bar(reinterpret_cast<void*>(&foo<int>::my_callback));

所以我的问题是 - 为什么这种明显的行为差异?

So my question is - why this apparent difference in behaviour?

推荐答案

从n3290,14.7.1隐式实例化[temp.inst]

From n3290, 14.7.1 Implicit instantiation [temp.inst]


2除非函数模板专门化已经显式地被
实例化或显式专门化,否则当专业化是在需要存在函数定义的上下文中引用的
时,隐式地实例化函数模板
specialization。

2 Unless a function template specialization has been explicitly instantiated or explicitly specialized, the function template specialization is implicitly instantiated when the specialization is referenced in a context that requires a function definition to exist.

在第1段中有类模板特化的类似规则。注意,该标准以专业化的方式表示,因为当使用模板时隐含地声明专业化,至少对于功能模板(第8段)没有用户提供的专门化。

There are similar rules in paragraph 1 for class template specializations. Notice that the Standard speaks in terms of specialization because a specialization is implicitly declared when a template is used an no user-provided specialization is here, at least for function templates (paragraph 8).

结合第10段,


10实现不应隐式实例化一个函数
模板,非虚拟成员函数,成员
类或不是
的类模板的静态数据成员需要实例化。

10 An implementation shall not implicitly instantiate a function template, a member template, a non-virtual member function, a member class, or a static data member of a class template that does not require instantiation.

我认为经验法则是:只要一个对象/类成员/函数需要或者使程序以其他方式工作(非正式地讲话),模板就被隐式实例化, 。

I think the rule of thumb is: as soon as an object/class member/function is needed or to make the program otherwise work (speaking informally), the template is implicitly instantiated but no sooner. This include taking the address of a function.

对于你链接的问题, reinterpret_cast 的一些用法可能会使程序不符合,此时与提示实例无关 - 我邀请您在那里看到我的答案 / shameless>。

As to the question you linked, some uses of reinterpret_cast may make the program non-conformant, by which time it's irrelevant to mention instantiations -- I invite you to see my answer there</shameless>.

这篇关于采用地址时,模板类型(类/函数)的实例化规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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