C++ 未定义的引用(使用静态库编译g+;+;)
项目文件如下所示:C++ 未定义的引用(使用静态库编译g+;+;),c++,g++,unix-ar,C++,G++,Unix Ar,项目文件如下所示: source parser parser.cpp parser.hpp brain brain.cpp brain.hpp 我首先运行了这两个命令(pwdsource/brain/): 我将brain.a和brain.hpp复制到source/parser/。然后我运行了这个命令(pwdsource/parser): 我得到了这个错误: /tmp/cceGRLZn.o: In function `main': parser.cpp:(
source
parser
parser.cpp
parser.hpp
brain
brain.cpp
brain.hpp
我首先运行了这两个命令(pwdsource/brain/
):
我将brain.a
和brain.hpp
复制到source/parser/
。然后我运行了这个命令(pwdsource/parser
):
我得到了这个错误:
/tmp/cceGRLZn.o: In function `main':
parser.cpp:(.text+0x1cc): undefined reference to `std::brain<long long>::brain()'
parser.cpp:(.text+0x205): undefined reference to `std::brain<long long>::init(int)'
parser.cpp:(.text+0x26b): undefined reference to `std::brain<long long>::work()'
parser.cpp:(.text+0x2a4): undefined reference to `std::brain<long long>::clear()'
parser.cpp:(.text+0x2ec): undefined reference to `std::brain<long long>::~brain()'
parser.cpp:(.text+0x322): undefined reference to `std::brain<long long>::~brain()'
/tmp/cceGRLZn.o: In function `int parser_extract_args<long long>(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int, short&, std::brain<long long>&)':
parser.cpp:(.text._Z19parser_extract_argsIxEiRSsiRsRSt5brainIT_E[int parser_extract_args<long long>(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int, short&, std::brain<long long>&)]+0x17b): undefined reference to `std::brain<long long>::push_back(long long)'
parser.cpp:(.text._Z19parser_extract_argsIxEiRSsiRsRSt5brainIT_E[int parser_extract_args<long long>(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int, short&, std::brain<long long>&)]+0x37a): undefined reference to `std::brain<long long>::push_back(long long)'
collect2: ld returned 1 exit status
我该怎么办?我打赌您在
.cpp
文件中实现了类模板brain
的成员函数。您需要在头文件中提供模板定义,以便编译器在看到模板实例化时可以生成适当的代码。因此,将brain.cpp
的内容向上移动到brain.h
作为一个例子,考虑这三个文件:
test.h
template <typename T> struct test { void foo(T); };
template <typename T> struct test { void foo(T); }; // Alternatively, you can define this up in the class definition void test<T>::foo(T x) { // do something with x }
main.cpp
#include "test.h" template <typename T> void test<T>::foo(T x) { // do something with x }
#include "test.h" int main() { test<int> t; t.foo(5); }
#include "test.h" int main() { test<int> t; t.foo(5); }
main.cpp
#include "test.h" template <typename T> void test<T>::foo(T x) { // do something with x }
#include "test.h" int main() { test<int> t; t.foo(5); }
#include "test.h" int main() { test<int> t; t.foo(5); }
#包括“test.h” int main() { 试验t; t、 傅(5),; }
std
命名空间:
<> > C++程序的行为如果在命名空间STD或名称空间<代码> STD< /COD>中添加命名空间或定义,则是未定义的,除非另有说明。
我打赌您在
.cpp
文件中实现了类模板brain
的成员函数。您需要在头文件中提供模板定义,以便编译器在看到模板实例化时可以生成适当的代码。因此,将brain.cpp
的内容向上移动到brain.h
作为一个例子,考虑这三个文件:
test.h
template <typename T> struct test { void foo(T); };
template <typename T> struct test { void foo(T); }; // Alternatively, you can define this up in the class definition void test<T>::foo(T x) { // do something with x }
main.cpp
#include "test.h" template <typename T> void test<T>::foo(T x) { // do something with x }
#include "test.h" int main() { test<int> t; t.foo(5); }
#include "test.h" int main() { test<int> t; t.foo(5); }
main.cpp
#include "test.h" template <typename T> void test<T>::foo(T x) { // do something with x }
#include "test.h" int main() { test<int> t; t.foo(5); }
#include "test.h" int main() { test<int> t; t.foo(5); }
#包括“test.h” int main() { 试验t; t、 傅(5),; }
std
命名空间:
<> > C++程序的行为如果在命名空间STD或名称空间<代码> STD< /COD>中添加命名空间或定义,则是未定义的,除非另有说明。
首先:不要向
std
命名空间添加任何实体。这将使程序具有未定义的行为
从您的消息中,您似乎已将名为brain
的类添加到std
命名空间中。从std
名称空间中删除brain
,并将其放入您的某个名称空间中。唯一可以添加到std
命名空间的是属于std
命名空间的模板的专门化
其次,除非您提供在整个程序中使用的类模板的显式实例化,您应该将类模板的成员函数的定义放在包含其声明的相同头文件中,以确保它们从实例化点可见
将它们放在一个单独的
.cpp
文件中会使编译器无法为正在从包含其定义的转换单元以外的其他转换单元调用的成员函数生成代码。也可能对您有所帮助。首先:不要向std
命名空间添加任何实体。这将使程序具有未定义的行为
从您的消息中,您似乎已将名为brain
的类添加到std
命名空间中。从std
名称空间中删除brain
,并将其放入您的某个名称空间中。唯一可以添加到std
命名空间的是属于std
命名空间的模板的专门化
其次,除非您提供在整个程序中使用的类模板的显式实例化,您应该将类模板的成员函数的定义放在包含其声明的相同头文件中,以确保它们从实例化点可见
将它们放在一个单独的
.cpp
文件中会使编译器无法为正在从包含其定义的转换单元以外的其他转换单元调用的成员函数生成代码。也可能对您有所帮助。您需要使用所需的类型声明brain template类的实例,因此在brain.cpp文件的末尾,您应该放:
template class brain <long long> ;
模板类大脑;
编译brain.cpp时,除非其中包含模板说明符,否则它不会创建任何可链接的代码,因为如果没有类型声明,它无法实例化模板类。也就是说,在使用模板类时,最好将它们保留为纯头文件您需要声明一个具有所需类型的brain模板类实例,因此在brain.cpp文件末尾,您应该:
template class brain <long long> ;
模板类大脑;
编译brain.cpp时,除非其中包含模板说明符,否则它不会创建任何可链接的代码,因为如果没有类型声明,它无法实例化模板类。也就是说,在使用模板类时,最好将它们保留为纯头文件似乎您是通过头文件和源文件使用模板,您需要在头文件中定义这些模板并将其包括在内。您能告诉我如何使用这些模板吗,这是我第一次使用模板,或者至少请参考一个教程。似乎您是通过页眉和源代码使用模板,您需要在页眉中定义这些模板并包含它们。您能告诉我如何使用这些模板吗?这是我第一次使用模板,或者至少请参考一个教程。