【问题标题】:How do I explicitly instantiate a template function?如何显式实例化模板函数?
【发布时间】:2011-06-23 09:56:33
【问题描述】:

我有一个带有一个参数的模板函数。 我必须实例化该函数而不调用该函数意味着我必须明确地实例化。

我有这个功能:

template <class T> int function_name(T a) {}

我这样实例化了那个函数:

template int function_name<int>(int);

但我收到以下错误:

error: expected primary-expression before 'template'
error: expected `;' before 'template'

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    [编辑 2]:请注意,由于代码格式问题,原始问题中的代码存在一些混淆。有关详细信息,请参阅 AnthonyHatchkins 的回答。

    如果您真的想实例化(而不是专门化或其他)函数,请执行以下操作:

    template <typename T> void func(T param) {} // definition
    
    template void func<int>(int param); // explicit instantiation.
    

    [编辑] 关于显式实例化和专业化似乎(很多)混淆。 我在上面发布的代码处理显式实例化specialization 的语法不同。 这是专门化的语法:

    template <typename T> void func(T param) {} // definition
    
    template <> void func<int>(int param) {} // specialization
    

    注意模板后面的尖括号!

    【讨论】:

    • 那是实例化还是专业化
    • 不正确。您可以告诉编译器显式实例化模板。谷歌“C++显式模板实例化”了解更多详情。
    • @Nawaz:你错了。当然,实例化始终是编译器,该行是程序员对编译器的实例化模板的请求。如果您有 C++ 标准的副本,请阅读 14.7.2 显式实例化
    • 专业化意味着你可能正在改变它的实现。实例化只是意味着您将其分配给特定的编译单元,可能是为了获取其唯一地址或使其作为库函数可用或减少膨胀。
    • @hrnt:我想,你是对的。 @Ashot:我刚刚注意到语法没有 template&lt;&gt; 形式。他写的和specialization不同。 +1 教我这个新东西。我正在删除我的帖子。 :D
    【解决方案2】:

    您的代码是正确的。

    错误消息与代码中您未在此处引用的位置有关。

    更新:

    原来的代码是

    template <class T> int function_name(T a) {}
    template int function_name<int>(int);
    

    这是正确的。

    但它没有被引用,因此看起来是这样的:

    template int function_name(T a) {}
    template int function_name(int);
    

    它会产生以下错误

    a.cpp:1: error: explicit instantiation of non-template ‘int function_name’
    a.cpp:1: error: expected `;' before ‘(’ token
    a.cpp:3: error: ‘function_name’ is not a template function
    

    这与 OP 引用的内容明显不同。

    在这个变体中,第二行是好的(&lt;int&gt; 可以在这里省略),但第一行是错误的。编译器无法猜测T 是模板参数。

    【讨论】:

    • 技术上这不是他的代码,而是比尔的编辑 :) 原始代码是 template int function_name( T a) { }template int function_name(int);
    • @hrnt 原始代码的格式不正确,但它是正确的。如果我是Balaji,如果他认为有用,我会返回并接受您的回答,但对我(可能对其他任何人)而言,您的回答(虽然本身完全正确)并不能回答问题.
    • @hrnt 你说得对,原来的代码是这样的。但是由于推导出的模板参数它仍然有效。我必须同意 Antony Hatchkins 的观点,即错误是由 OP 未引用的代码引起的,但是我认为您的回答对于不了解显式实例化的人仍然有用。
    • 好吧,以我为例。当我想刷新我被遗忘的关于显式实例化的知识时,我用谷歌搜索了这个页面——它对我没有多大帮助。至于我,语法没有混淆。显式实例化可能导致混淆的是它的用法
    • @AntonyHatchkins 啊,是的 - 我没有看原始问题的来源,只是看它是如何出现在我的屏幕上的。我会对此 +1 并修改我原来的答案,以说明对原始问题的混淆。
    【解决方案3】:

    当我们要拆分 cpp/hpp 文件时,这可能有助于实例化模板方法。

    // foo.hpp
    
    struct Foo
    {
        template<typename T>
        void myMethod(T var);
    };
    
    
    // foo.cpp
    #include <typeinfo>
    #include <iostream>
    
    template void Foo::myMethod(int var);
    
    template void Foo::myMethod(double var);
    
    template <typename T>
    void Foo::myMethod(T var)
    {
        std::cout << typeid(T).name() << " - " << var << std::endl;
    }
    

    例子:

        Foo foo;
        foo.myMethod(1);
        foo.myMethod(2.0);
        
        // undefined reference to `void Foo::myMethod(float)'
        // foo.myMethod(2.0F); <-- doesn't work as we don't have definition
    
    OUT:
    i - 1
    d - 2
    

    你可以在这里玩:https://onlinegdb.com/gwAjMF9QH

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-15
      • 2014-02-26
      • 2011-10-07
      • 2012-02-11
      • 1970-01-01
      • 2013-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多