【问题标题】:Declaration of specialized function in template class模板类中的专用函数声明
【发布时间】:2013-10-22 19:01:21
【问题描述】:

我正在努力解决的问题是在模板类中声明专用模板函数(我将类声明保留在头文件中,并在关联的 .C 文件中定义成员函数)。

我有代表点的模板类。头文件如下:

//...

template<typename T, int dim=3> // T - coords. type, int dim - no. of dimensions
class Point {
    public:
        // ...
        // function below sets val at the given position in array m_c and returns reference
        template<int position> Point& set(T val); 
    private:
        T m_c[dim]; // coordinates
};

//...

函数set的定义放在.C文件中:

template<typename T, int dim> template<int position> Point<T, dim>& Point<T, dim>::set(T val){
    // ...
    return *this;
}

据我了解,这是其定义的最一般形式。

在主函数中,我将Pointfloat 创建为T,并尝试在数组中设置一些值:

int main(int argc, char** argv) {
    Point<float> p1;
    p1.set<0>(3).set<1>(3.6).set<2>(3);
    //...
}

为了通过在头文件外部定义模板的成员函数来实现这一点,我需要通知编译器关于 .C 文件中的特化:

template class Point&lt;float&gt;;

我还需要声明 set 函数的用法,我尝试以这种方式完成 (而这段代码就是问题所在):

template&lt;&gt; template&lt;int&gt; Point&lt;float&gt;&amp; Point&lt;float&gt;::set(float);

不幸的是,这不起作用,我得到了错误:

/tmp/ccR7haA5.o: In function `main':
.../pdim.C:32: undefined reference to `Point<float, 3>& Point<float, 3>::set<0>(float)'
.../pdim.C:32: undefined reference to `Point<float, 3>& Point<float, 3>::set<1>(float)'
.../pdim.C:32: undefined reference to `Point<float, 3>& Point<float, 3>::set<2>(float)'

我非常感谢知道如何解决这个问题的人的解释。谢谢。

【问题讨论】:

  • 为了在无法实例化 set 的 TU 中使用 set 的特化,您需要从实例化它的 TU“导出”所需的特定特化(我将必须查找语法)。
  • 不幸的是,提议的主题与我的问题无关。我想知道如何声明这样的函数:template&lt;int position&gt; Point&amp; set(T val); - 在我的理解中如何告诉编译器生成足够的代码。在此示例中与 Point&lt;float&gt; 类的实例一起使用。那里:link 是一些有用的提示,但引用了未指定类型的模板成员函数。
  • 前。 extern template Point&lt;float&gt;&amp; Point&lt;float&gt;::set&lt;0&gt;(float);
  • 注意:不需要显式实例化类模板;成员函数的定义不需要可用于实例化类模板。

标签: c++ templates specialization


【解决方案1】:

为了在不同的 TU 中提供函数模板特化的定义,您需要显式的实例化声明:

[Point.hpp]

template<typename T, int dim=3>
struct Point
{
    template<int position> Point& set(T val);
};

// `extern` makes this an explicit instantiation _declaration_
extern template Point<float,3>& Point<float,3>::set<0>(float);
extern template Point<float,3>& Point<float,3>::set<1>(float);
extern template Point<float,3>& Point<float,3>::set<2>(float);

[Point.cpp]

#include <iostream>
#include "Point.hpp"

template<typename T, int dim>
template<int position>
Point<T,dim>& Point<T,dim>::set(T val)
{
    // note: non-standard macro
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    return *this;
}

// no `extern`: this is an explicit instantiation _definition_
// which instantiates the function template, and therefore requires the definition
// to be available in this TU
template Point<float,3>& Point<float,3>::set<0>(float);
template Point<float,3>& Point<float,3>::set<1>(float);
template Point<float,3>& Point<float,3>::set<2>(float);

[main.cpp]

#include "Point.hpp"

int main()
{
    // in this TU, there's no definition for the function template
    // hence, it cannot be instantiated
    // however, we can use the explicit instantiations

    Point<float,3>().set<0>(0);
    Point<float,3>().set<1>(0);
    Point<float,3>().set<2>(0);

    // does not compile (linker error):
    //Point<int,3>().set<0>(0);
    //Point<float,4>().set<0>(0);
    //Point<float,3>().set<4>(0);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多