"undefined reference"从静态方法访问的模板类的静态成员

"undefined reference" to static member of template class accessed from static method

本文关键字:静态成员 访问 undefined reference 静态方法      更新时间:2023-10-16

我有一个静态类方法,它需要访问指针MyTypePointer,因此必须声明为静态。由于它是一个模板类,我必须将方法放在头文件中,但我不能在头中定义MyTypePointer。

因此,由于没有声明MyTypePointer,我得到了"未定义引用"错误。我如何使此项工作/声明MyTypePointer。

myclass.h
template <typename A, typename B>
class PathfindingClass {
    typedef std::vector<GenericEdgeClass<A, B>*> MyType;
    static MyType *MyTypePointer;
};
template <typename A, B>
void MyClass<A, B>::MyMethod(int x, int y) { 
    //do something with MyTypePointer
}

非常感谢。

这是一个完整参考的迟交答案,因为这个问题被链接为另一个问题的参考。

声明但未定义的静态字段的最小破坏示例可以是:

template<typename T>
class A
{
public:
    static T val;
    static void init()
    {
        val=0;
    }
};
int main()
{
    // A::init();
    A<double>::init();
    return 0;
}

修复方法只是在类定义之后定义静态字段:

template<typename T>
class A
{
public:
    static T val;
    static void init()
    {
        val=0;
    }
};
template<typename T> T A<T>::val; // only change here
int main()
{
    // A::init();
    A<double>::init();
    return 0;
}

在模板定义中,static MyType *MyTypePointer;声明一个对象。您仍然需要在模板类定义之外定义它:

template <class A, class B>
typename PathfindingClass<A, B>::MyType*
PathfindingClass<A, B>::MyTypePointer;

您仍然可以定义模板成员,并为所有需要的专业化显式实例化它。如果您坚持在类模板中有一个state数据成员,这大致就是所需要的。

考虑到全局变量共享各种各样的问题,包括初始化期间的依赖性问题,您最好使用static成员函数包装数据成员:

template <typenane T>
class foo {
    // ...
    static X*& member() {
        static X* rc = ...;
        return rc;
    }
};

本地变量在第一次调用函数时初始化,并且可以安全地使用对它的引用。这种方法也适用于模板。

注意,我仍然建议避免全局变量!它们会在长期和短期内造成许多问题。使用它们的好处是一笔巨大的债务,通常无法偿还。