【问题标题】:Will the pointer to a template member function inside a constructor force instantiation?指向构造函数内的模板成员函数的指针会强制实例化吗?
【发布时间】:2011-04-20 09:57:45
【问题描述】:

考虑以下头文件:

// Foo.h
class Foo {
    public: template <typename T> void read(T& value);
};

似乎在类的构造函数中分配一个指向Foo::read&lt;T&gt;的指针,然后声明该变量,导致实例化:

// Foo.cc
#include "Foo.h"

template <typename T>
void Foo::read(T& value) { /* do something */ }

template <typename T> struct Bar {
    Bar<T>() { void (Foo::*funPtr)(T&) = &Foo::read<T>; }
};

static Bar<int  > bar1;
static Bar<long > bar2;
static Bar<float> bar3;

此解决方案是否可靠/便携/符合标准? (它至少适用于 Intel 和 GNU 编译器。)

如果您想知道为什么不直接使用template Foo::read&lt;int&gt;(int&amp;);,请参阅this question

【问题讨论】:

  • “此解决方案是否可靠/便携/符合标准?”。对不起。我在你的问题中找不到问题陈述。怎么可能有没有问题的解决方案?
  • @Johannes:如果不清楚,请参阅链接的问题了解详细信息。我只是不知道,这种“强制显式实例化”是否适用于所有符合标准的编译器。

标签: c++ templates constructor instantiation explicit


【解决方案1】:

是的,您的解决方案是可移植的。这是另一种方式

template <typename T, T> struct user { };
template <typename T> struct Bar {
    typedef user< void (Foo::*)(T&), &Foo::read<T> > user_type;
};

现在,无论何时隐式实例化 Bar&lt;T&gt;,它都会隐式实例化 Foo::read&lt;T&gt;。不需要创建对象。

【讨论】:

    【解决方案2】:

    14.7.1 就是它所在的位置。 /2 说:

    除非函数模板 专业化已经明确 实例化或显式 专门的,功能模板 专业化是隐含的 特化时实例化 在上下文中引用 需要一个函数定义 存在。

    就像调用函数一样,获取成员函数指针需要在程序中定义函数(可能在另一个 TU 中)。我相信这就是“需要一个函数定义存在”的意思,所以这就是导致实例化的原因。

    还有/9:

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

    所以 GCC 和 Intel 实例化它的事实表明其他人都应该这样做,因为不需要的东西是被禁止的。当然,假设每个人都遵守。

    【讨论】:

      【解决方案3】:

      Bar&lt;type&gt; 的对象被声明为实际类型时,肯定是,是的;它将实例化Foo::read&lt;type&gt;()。但是,它将仅限于该函数(比如Foo::write&lt;type&gt;() 不会被实例化)。

      另外,如果你尝试这样的事情:

      template<typename T>
      struct X
      {
        Bar<T> b1;  // this is required but not sufficient to instantiate Foo::read<T>()
      };
      

      那么在你声明X&lt;int&gt;之前,Foo::read&lt;int&gt;()不会被实例化。

      编辑: 在上面的例子中,在X 中直接声明Bar&lt;int&gt; b1;int 而不是T)也是不够的。它的包含类型X&lt;&gt; 必须用实际(即非模板)类型实例化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-13
        • 2020-09-20
        • 1970-01-01
        • 1970-01-01
        • 2011-12-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多