在尝试运行在非模板化类中具有模板化函数的程序时,我收到了undefiend reference
错误消息。在这个帖子的评论中提出了多个解决方案,我选择的那个解决方案在本文末尾进行了说明。
参见"问题陈述"下面是我的代码输出的错误。
编辑1:2017年12月8日:
编辑2:2017年12月19日:
使用g++
编译和链接我的类文件,这给了我{driver}调用undefined reference
的{{1}}投诉。显然它无法在mergesortImproved.cpp中找到我的函数的定义。
mergesortImproved::beginSorting(std::vector<int> &data)
旁注,msI是我缩写mergesortImproved的方式。这是教师所需的文件名,但看到它有点麻烦,我已经把它称为msI。
我这样说,以防msI弹出某个地方,我忘了在这篇文章中将名称更改为mergesortImproved。
所有文件都在同一个文件夹中,我确保在尝试编译和链接时包含所有文件。
我还尝试在Windows 10计算机和Linux计算机上进行编译。
我已经阅读了许多其他类似的问题,似乎这个问题的10倍中有9个来自程序员没有编译程序的所有文件,如应该。所以......
编辑:几乎忘了包含我试图使用的Windows和Linux机器的g ++版本。
对于Windows 10计算机:
$ g++ -o msI_out -std=c++17 *.cpp
/tmp/ccZ0tzev.o: In function `generateTimeData(quicksort&, mergesort&, mergesortImproved&, int const&, long double&, std::vector<int, std::allocator<int> >&)':
driver.cpp:(.text+0xaac): undefined reference to `void mergesortImproved::beginSorting<int>(std::vector<int, std::allocator<int> >&)'
collect2: error: ld returned 1 exit status
对于Linux机器:
>gcc -v
"crazy alphabet-soup pops up, followed by:"
Thread model: posix
gcc version 7.2.0 (x86_64-posix-seh-rev1, Built by MinGW-W64 project)
请注意下面显示的控制台输出行:
所有错误响应最初都是非常长的单行输出。为了更容易阅读,我已经冒昧地将输出分成多行。
即,不必搜索$gcc -v
"like windows, it starts with crazy alphabet-soup, followed by:"
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
的位置,以及重复格式的其他视觉提示。
Linux尝试
Linux_attempt-1:
undefined reference
(我在上面的问题陈述中显示的错误相同)
Linux_attempt-2:
$ g++ -o msI_out -std=c++17 *.cpp
In function `generateTimeData(quicksort&, mergesort&, mergesortImproved&, int const&, long double&, std::vector<int, std::allocator<int> >&)':
driver.cpp:(.text+0xaac): undefined reference to `void mergesortImproved::beginSorting<int>(std::vector<int, std::allocator<int> >&)'
collect2: error: ld returned 1 exit status
(我在上面的问题陈述中显示的错误相同)
Linux_attempt-3:
$ g++ -o msI_out -std=c++17 driver.cpp quicksort.cpp mergesortImproved.cpp mergesort.cpp WorkDir.cpp
/tmp/ccQzfFiq.o: In function `generateTimeData(quicksort&, mergesort&, mergesortImproved&, int const&, long double&, std::vector<int, std::allocator<int> >&)':
driver.cpp:(.text+0xaac): undefined reference to `void mergesortImproved::beginSorting<int>(std::vector<int, std::allocator<int> >&)'
collect2: error: ld returned 1 exit status
Windows 10尝试
Windows_attempt-1:
$ g++ -c -std=c++17 driver.cpp quicksort.cpp mergesortImproved.cpp mergesort.cpp WorkDir.cpp
$ g++ -o msI_out -std=c++17 driver.o quicksort.o mergesortImproved.o mergesort.o WorkDir.o
driver.o: In function `generateTimeData(quicksort&, mergesort&, mergesortImproved&, int const&, long double&, std::vector<int, std::allocator<int> >&)':
driver.cpp:(.text+0xaac): undefined reference to `void mergesortImproved::beginSorting<int>(std::vector<int, std::allocator<int> >&)'
collect2: error: ld returned 1 exit status
Windows_attempt-2:
>g++ -o msI_out -std=c++17 *.cpp
\cc1alJ9m.o:driver.cpp:(.text+0x94f): undefined reference to `void mergesortImproved::beginSorting<int>(std::vector<int, std::allocator<int> >&)'
collect2.exe: error: ld returned 1 exit status
Windows_attempt-3:
>g++ -o msI_out -std=c++17 driver.cpp mergesort.cpp quicksort.cpp mergesortImproved.cpp WorkDir.cpp
\ccGBGXAX.o:driver.cpp:(.text+0x94f): undefined reference to `void mergesortImproved::beginSorting<int>(std::vector<int, std::allocator<int> >&)'
collect2.exe: error: ld returned 1 exit status
>g++ -c -std=c++17 driver.cpp quicksort.cpp mergesortImproved.cpp mergesort.cpp WorkDir.cpp
>g++ -o msI_out -std=c++17 driver.o quicksort.o mergesortImproved.o mergesort.o WorkDir.o
driver.o:driver.cpp:(.text+0x94f): undefined reference to `void mergesortImproved::beginSorting<int>(std::vector<int, std::allocator<int> >&)'
collect2.exe: error: ld returned 1 exit status
// driver.cpp
#include <iostream>
#include <vector>
#include "mergesortImproved.h"
using namespace std;
/** int main( int argc, char *argv[] )
*
* main(arc, argv) will perform the task of initializing sorting classes, output files, and control variables.
*
*
* @param argc The number of arguments passed on the command line.
* If argc == 1, then no additional arguments were passed, as the first argument is always the
* name of the executable file.
*
* @param argv An array of c_strings containing any command-line arguments beyond the initial executable's name.
* @return the error code should any be thrown, otherwise 0 when all goes well.
*/
int main( int argc, char *argv[] )
{
vector<int> sampleVector = {41, 8467, 6334, 6500, 9169, 5724, 1478, 9358, 6962, 4464, 5705, 8145, 3281, 6827};
mergesortImproved msI;
msI.beginSorting(sampleVector);
return 0;
}
#ifndef MSI_ASSIG4_MERGESORTIMPROVED_H
#define MSI_ASSIG4_MERGESORTIMPROVED_H
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
using namespace std;
class mergesortImproved
{
public:
/** template<class Comparable> void beginSorting(vector<Comparable> &data)
*
* Handles preparations for iterative-in-place Mergesort. Namely, the math needed for locating and saving index pointers into
* queues and stacks that will later be used to emulate recursively subdeviding the unsorted collection before the much
* simpler task of recombining the imaginary subdivisions.
*
* @tparam Comparable This template reference is meant for use with data types that possess natural ordering.
* Although there are no assert restrictions in place to ensure you only use data types with natural
* ordering, the problem should become quickly apparant if the programmer fails to respect this
* requirement.
*
* @param data The vector<Comparable> that is to be sorted
*/
template<class Comparable>
void beginSorting(vector<Comparable> &vector);
/** template <class Comparable> mergesortImproved(vector<Comparable> &data)
*
* @tparam Comparable This template reference is meant for use with data types that possess natural ordering.
* Although there are no assert restrictions in place to ensure you only use data types with natural
* ordering, the problem should become quickly apparant if the programmer fails to respect this
* requirement.
*
* @param data The vector<Comparable> that is to be sorted
*/
template <class Comparable>
mergesortImproved(vector<Comparable> &data)
{
beginSorting(data);
}
mergesortImproved()=default;
private:
// omitted
};
#endif //MSI_ASSIG4_MERGESORTIMPROVED_H
(driver.cpp与以前完全没有变化,但是我已经在这里展示了它的代码,以便在看到事物如何结合在一起时视觉上的轻松。)
#include "mergesortImproved.h"
using namespace std;
/** template<class Comparable> void beginSorting(vector<Comparable> &data)
*
* Handles preparations for iterative-in-place Mergesort. Namely, the math needed for locating and saving index pointers into
* queues and stacks that will later be used to emulate recursively subdeviding the unsorted collection before the much
* simpler task of recombining the imaginary subdivisions.
*
* @tparam Comparable This template reference is meant for use with data types that possess natural ordering.
* Although there are no assert restrictions in place to ensure you only use data types with natural
* ordering, the problem should become quickly apparant if the programmer fails to respect this
* requirement.
*
* @param data The vector<Comparable> that is to be sorted
*/
template<class Comparable>
void mergesortImproved::beginSorting(vector<Comparable> &data)
{
// dummy functionality here, just demonstrating the conditions causing the linker error
cout << "Hey, it's running!!" << endl;
}
// driver.cpp
#include <iostream>
#include <vector>
#include "mergesortImproved.h"
using namespace std;
/** int main( int argc, char *argv[] )
*
* main(arc, argv) will perform the task of initializing sorting classes, output files, and control variables.
*
*
* @param argc The number of arguments passed on the command line.
* If argc == 1, then no additional arguments were passed, as the first argument is always the
* name of the executable file.
*
* @param argv An array of c_strings containing any command-line arguments beyond the initial executable's name.
* @return the error code should any be thrown, otherwise 0 when all goes well.
*/
int main( int argc, char *argv[] )
{
vector<int> sampleVector = {41, 8467, 6334, 6500, 9169, 5724, 1478, 9358, 6962, 4464, 5705, 8145, 3281, 6827};
mergesortImproved msI;
msI.beginSorting(sampleVector);
return 0;
}
#ifndef MSI_ASSIG4_MERGESORTIMPROVED_H
#define MSI_ASSIG4_MERGESORTIMPROVED_H
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
class mergesortImproved
{
public:
/** template<class Comparable> void beginSorting(vector<Comparable> &data)
*
* Handles preparations for iterative-in-place Mergesort. Namely, the math needed for locating and saving index pointers into
* queues and stacks that will later be used to emulate recursively subdeviding the unsorted collection before the much
* simpler task of recombining the imaginary subdivisions.
*
* @tparam Comparable This template reference is meant for use with data types that possess natural ordering.
* Although there are no assert restrictions in place to ensure you only use data types with natural
* ordering, the problem should become quickly apparant if the programmer fails to respect this
* requirement.
*
* @param data The vector<Comparable> that is to be sorted
*/
template<class Comparable>
void mergesortImproved::beginSorting(std::vector<Comparable> &data)
{
// dummy functionality here, just demonstrating the conditions causing the linker error
cout << "Hey, it's running!!" << endl;
}
/** template<class Comparable> void beginSorting(vector<Comparable> &data)
*
* Handles preparations for iterative-in-place Mergesort. Namely, the math needed for locating and saving index pointers into
* queues and stacks that will later be used to emulate recursively subdeviding the unsorted collection before the much
* simpler task of recombining the imaginary subdivisions.
*
* @tparam Comparable This template reference is meant for use with data types that possess natural ordering.
* Although there are no assert restrictions in place to ensure you only use data types with natural
* ordering, the problem should become quickly apparant if the programmer fails to respect this
* requirement.
*
* @param data The vector<Comparable> that is to be sorted
*/
template<class Comparable>
void beginSorting(vector<Comparable> &vector);
/** template <class Comparable> mergesortImproved(vector<Comparable> &data)
*
* @tparam Comparable This template reference is meant for use with data types that possess natural ordering.
* Although there are no assert restrictions in place to ensure you only use data types with natural
* ordering, the problem should become quickly apparant if the programmer fails to respect this
* requirement.
*
* @param data The vector<Comparable> that is to be sorted
*/
template <class Comparable>
mergesortImproved(vector<Comparable> &data)
{
beginSorting(data);
}
mergesortImproved()=default;
private:
// omitted
};
#endif //MSI_ASSIG4_MERGESORTIMPROVED_H