c++ - 获取地址时模板类型(类/函数)实例化的规则是什么?

标签 c++ templates

在回答this问题,我在模板实例化方面遇到了这种行为差异。

最初有一个函数模板

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

现在有些东西需要 this 的地址 - 特别是 void*,所以显而易见的方法是

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

但是,对于 gcc 4.5 之前的编译器版本,此操作失败并出现上下文不足...错误。很好 - 所以解决方法是先“施放” - 这会强制实例化,即:

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

这很好用。

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

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));

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

最佳答案

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

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 段)是这样。

结合第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.

我认为经验法则是:一旦需要一个对象/类成员/函数或使程序以其他方式工作(非正式地说),模板就会被隐式实例化,但不久 .这包括获取函数的地址。

关于您链接的问题,reinterpret_cast 的一些使用可能会使程序不符合要求,到那时提及实例化是无关紧要的 -- I invite you to see my answer there </无耻>。

关于c++ - 获取地址时模板类型(类/函数)实例化的规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6735720/

相关文章:

c++ 无序列表示例

c++ - 为什么 cin 在包含字符串头后接受字符串输入

c++ - 将 CTAD 与多个模板参数包一起应用

c++ - 带有模板的类实例的外部

c++ - 具有std::enable_if_t的模板类,静态const成员初始化

c++ - 指向成员基函数的模板指针

css - 如何禁用 blogger.com 网站中的动态 View 下拉列表?

c++ - 通过引用访问器访问私有(private)成员

c++ - 在 C++ 中嵌入 Lua : linkage problems (liblua5. 1.a)

c++ - 统一调用语法的 C++17 提案打算如何处理 namespace ?