C++ - 模板 Class -> 静态函数 -> Link 静态函数指针错误
C++ - Template Class -> Static function -> Link error for static function pointer
波纹管代码在 Visual studio & Solaris 编译器上成功编译。但是在 g++ (SUSE Linux) 4.3.4 中出现 link 错误。请让我知道如何解决 linux 上的 link 错误?
注意:为了使代码简单明了,我在这里输入了代理代码。
//---------------- a1.h ----------
#ifndef __a1_h__
#define __a1_h__
#include <iostream>
#include <memory>
namespace ServiceManagement
{
template <typename T>
class ClassA1
{
public:
ClassA1() {}
typedef std::auto_ptr<T>(*addFunc)(int, int);
static void setAddFunc(addFunc f)
{
s_AddFunc = f;
}
private:
static addFunc s_AddFunc;
};
}
#endif
//---------------- b1.h ----------
#ifndef __b11_h__
#define __b11_h__
#include "a1.h"
typedef ServiceManagement::ClassA1<int> setPosType;
namespace ServiceManagement
{
class ClassB1
{
public:
ClassB1() {}
static void Register();
private:
std::auto_ptr<setPosType> m_ptrMsg;
};
}
#endif
//---------------- b1.cpp ----------
#include "b1.h"
#include <iostream>
using namespace std;
//setPosType::addFunc setPosType::s_AddFunc;
template <> setPosType::addFunc setPosType::s_AddFunc;
namespace AA
{
namespace v2
{
std::auto_ptr<int> message2_(int a, int b)
{
int c = a + b;
std::auto_ptr<int> p1(new int);
*p1.get() = c;
return p1;
}
}
}
namespace ServiceManagement
{
void ClassB1::Register()
{
setPosType::addFunc f1 = ::AA::v2::message2_;
setPosType::setAddFunc(f1);
}
}
int main()
{
int i = 0;
cin >> i;
return 0;
}
Link 错误:
/usr/bin/c++ -pthread -g -w -W -Wall -Wno-long-long -g -ldl -lm -lnsl -m64 -o -pthread -std=gnu++0x -Bdynamic
.. build " CMakeFiles/templateTest.dir/b1.cpp.o -o ../../../../../..//templateTest -rdynamic
CMakeFiles/templateTest.dir/b1.cpp.o: 在函数中 **ServiceManagement::ClassA1<int>::setAddFunc(std::auto_ptr<int> (*)(int, int))'**:
/templateTest/**a1.h:18: undefined reference to
ServiceManagement::ClassA1::s_AddFunc'
collect2: ld 返回了 1 个退出状态**
注释 2:
已经在 b1.cpp 处定义了静态变量,如下所示,
模板 <> setPosType::addFunc setPosType::s_AddFunc;
1.) 一旦你初始化了成员变量就起作用了:
template <> setPosType::addFunc setPosType::s_AddFunc = 0;
显然,如果没有初始化程序,这一行是声明而不是定义,但是老实说,我不明白为什么。
2.) Clang 告诉我在其名称空间之外定义静态成员是 C++11 扩展。更好用
namespace ServiceManagement {
template <> setPosType::addFunc setPosType::s_AddFunc = 0;
}
波纹管代码在 Visual studio & Solaris 编译器上成功编译。但是在 g++ (SUSE Linux) 4.3.4 中出现 link 错误。请让我知道如何解决 linux 上的 link 错误? 注意:为了使代码简单明了,我在这里输入了代理代码。
//---------------- a1.h ----------
#ifndef __a1_h__
#define __a1_h__
#include <iostream>
#include <memory>
namespace ServiceManagement
{
template <typename T>
class ClassA1
{
public:
ClassA1() {}
typedef std::auto_ptr<T>(*addFunc)(int, int);
static void setAddFunc(addFunc f)
{
s_AddFunc = f;
}
private:
static addFunc s_AddFunc;
};
}
#endif
//---------------- b1.h ----------
#ifndef __b11_h__
#define __b11_h__
#include "a1.h"
typedef ServiceManagement::ClassA1<int> setPosType;
namespace ServiceManagement
{
class ClassB1
{
public:
ClassB1() {}
static void Register();
private:
std::auto_ptr<setPosType> m_ptrMsg;
};
}
#endif
//---------------- b1.cpp ----------
#include "b1.h"
#include <iostream>
using namespace std;
//setPosType::addFunc setPosType::s_AddFunc;
template <> setPosType::addFunc setPosType::s_AddFunc;
namespace AA
{
namespace v2
{
std::auto_ptr<int> message2_(int a, int b)
{
int c = a + b;
std::auto_ptr<int> p1(new int);
*p1.get() = c;
return p1;
}
}
}
namespace ServiceManagement
{
void ClassB1::Register()
{
setPosType::addFunc f1 = ::AA::v2::message2_;
setPosType::setAddFunc(f1);
}
}
int main()
{
int i = 0;
cin >> i;
return 0;
}
Link 错误: /usr/bin/c++ -pthread -g -w -W -Wall -Wno-long-long -g -ldl -lm -lnsl -m64 -o -pthread -std=gnu++0x -Bdynamic
.. build " CMakeFiles/templateTest.dir/b1.cpp.o -o ../../../../../..//templateTest -rdynamic
CMakeFiles/templateTest.dir/b1.cpp.o: 在函数中 **ServiceManagement::ClassA1<int>::setAddFunc(std::auto_ptr<int> (*)(int, int))'**:
/templateTest/**a1.h:18: undefined reference to
ServiceManagement::ClassA1::s_AddFunc'
collect2: ld 返回了 1 个退出状态**
注释 2: 已经在 b1.cpp 处定义了静态变量,如下所示, 模板 <> setPosType::addFunc setPosType::s_AddFunc;
1.) 一旦你初始化了成员变量就起作用了:
template <> setPosType::addFunc setPosType::s_AddFunc = 0;
显然,如果没有初始化程序,这一行是声明而不是定义,但是老实说,我不明白为什么。
2.) Clang 告诉我在其名称空间之外定义静态成员是 C++11 扩展。更好用
namespace ServiceManagement {
template <> setPosType::addFunc setPosType::s_AddFunc = 0;
}