【问题标题】:How do I force a particular instance of a C++ template to instantiate?如何强制 C++ 模板的特定实例实例化?
【发布时间】:2011-01-10 06:06:58
【问题描述】:

见标题。我有一个模板。我想强制模板的特定实例实例化。我该怎么做?

更具体地说,你能强制一个抽象模板类实例化吗?


我可能会详细说明,因为我有同样的问题。就我而言,我正在构建一个库,一些模板实现很大并且包含很多东西,但只为几种类型生成。我想在库中编译它们并导出所有方法,但不要在任何地方都包含带有代码的标头。

即:

template<class T>
OS_EXPORT_DECL class MyTmpl
{
    T *item1;
public:
    inline T *simpleGetT() { return(item1); } /* small inline code in here */ } 
    T *doSomeReallyBigMergeStuff(T *b); // note only declaration here
};

// *** implementation source file only seen inside library

template<class T>
MyTmpl<T>::doSomeReallyBigMergeStuff(T *b)
{
    ... a really big method, but don't want to duplicate it, 
        so it is a template ...
}

我当然可以引用库中的所有方法,这将迫使它们编译和导出,但不希望将不需要的代码添加到库中,例如项目的参数格式和调用它们的代码等等

?????具体来说,我正在为多个版本的 MSC 和 GCC 以及 intel 编译器构建库。

【问题讨论】:

  • 你能举个例子吗? “实例化抽象模板类”到底是什么意思?

标签: c++ templates instantiation


【解决方案1】:

你不能强制泛型模板实例化,编译器只能在类型完全已知的情况下生成代码。

通过显式提供所有类型来强制实例化:

template class std::vector<int>;

Comeaus template FAQ 详细介绍了相关问题。

【讨论】:

  • 请注意,在所有模板和代码都被声明为安全之后,您应该执行此操作。
  • @peterk“宣布安全”让我想了大约 20 秒。然后我突然意识到“在……被宣布之后,为了安全”。 -- 哈哈
  • 这实际上是一个语法错误,至少在 gcc 4.1 上;应该是template class std::vector&lt;int&gt;(下面亚历山大的回答是正确的)
【解决方案2】:

您还可以尝试显式实例化:

template class vector<int>;                    // class
template int& vector<int>::operator[](int);    // member
template int convert<int,double>(double);      // function

【讨论】:

  • 在我到达这篇文章之前,我尝试了几天使用模板,但我无法弄清楚问题出在哪里。仅使用没有尖括号的“模板”效果很好。
【解决方案3】:

您可以通过使用带有所需参数的模板来强制实例化。例如,您可以使用所有必需的方法定义一个函数:

void force_int_instance() {
  Abstract<int> *a;
  a->some_method();
  a->some_other_method(1, 2, 3);
}

您不需要在任何地方实际调用该函数,因此指针未初始化不是问题。但是编译器必须假设该函数可能是从另一个目标文件中调用的,所以它必须实例化模板。

【讨论】:

    【解决方案4】:

    如果我正确理解您的问题,您有一个模板类,并且您想强制编译器生成用于某些特定类型的代码。例如,您可能希望确保程序中存在 std::vector 的代码。

    确保这一点的最佳方法是简单地构造一个类的实例:

    void EnsureInstantiation()
    {
        std::vector<int> intvector;
        std::vector<boo> boolvector;
        /// etc.
    }
    

    诀窍是您甚至不必在代码中的任何位置调用 EnsureInstantiation。只要确保它不是静态的,否则编译器可能对其进行优化。

    【讨论】:

      【解决方案5】:

      抽象类不能被实例化。你可能想做一些类似的事情:

      Abstract *a = new Implementation(...);
      

      要强制模板实例化,使用模板参数调用模板:

      std::max<int>(...);
      std::pair<int, string>(...);
      

      【讨论】:

        【解决方案6】:

        我会回答我认为你的意思,而不是你所说的。

        我猜这个问题是两件事之一。首先是模板中的代码在编译模板文件本身时没有被编译,这可能很烦人。这可以在您的编译器设置中修复。

        另一个是你想为特定类型提供一些特殊的东西,也许是为了调试它。这称为显式实例化,但并没有真正实例化任何东西,只是确保它始终在该点之后定义。

        http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/topic/com.ibm.vacpp6m.doc/language/ref/clrc16explicit_instantiation.htm

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-09
          • 2017-03-19
          相关资源
          最近更新 更多