未命名的引用`void sort :: swap <int>(int *,int,int)'</int>

时间:2011-05-16 06:08:01

标签: c++ templates compiler-errors

  

可能重复:
  Why can templates only be implemented in the header file?

这是我的make文件:


#!/usr/bin/make -f
compiler = g++
compiler_flags = -Wall -I /usr/include/c++/4.5
debug_flags = -D DEBUG -g
binary_filename = sort_testing.bin

all: clean release

release: 
    $(compiler) $(compiler_flags) main.cpp sort.o -o $(binary_filename)
debug: sort.o 
    $(compiler) $(debug_flags) $(compiler_flags) main.cpp sort.o -o $(binary_filename)
run: 
    ./$(binary_filename)
clean: 
    rm -f *.o $(binary_filename)
sort.o: 
    $(compiler) $(debug_flags) $(compiler_flags) -c sort.cpp


以下是我的C ++文件:


// sort.hpp
#ifndef SORT_H
#define SORT_H

namespace sort{
    template<class T> void swap(T*,int,int);
}

#endif

// sort.cpp
#include "sort.hpp"

namespace sort{
    template<class T>
    void swap(T* items, int index_a, int index_b){
        T t = items[index_a];
        items[index_a] = items[index_b];
        items[index_b] = t;
    }
}

// main.cpp
#include <iostream>
#include <exception>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;

#include "sort.hpp"
using namespace sort;

#define NUM_INTS 5

int main(int argc, char** argv){
    try{
        cout << "\n\n\n";
        srand(time(NULL));
        int * int_coll = new int[NUM_INTS];
        for (int x = 0; x < NUM_INTS; x++)
            int_coll[x] = rand() % 100 + 1;
        cout << "Before swap" << endl;
        for (int x = 0; x < NUM_INTS; x++)
            cout << "int " << x << " == " << int_coll[x] << endl;
        cout << "\n\n\n";

        cout << "Swapping ints" << endl;
        swap<int>(int_coll, 0, 1);

        cout << "AFter swap" << endl;
        for (int x = 0; x < NUM_INTS; x++)
            cout << "int " << x << " == " << int_coll[x] << endl;
    }catch(exception& e){
        cout << "Exception:  " << e.what() << endl;
    }
    return 0;
}

而且,这是我的问题:

./make clean debug
rm -f *.o sort_testing.bin
g++ -D DEBUG -g -Wall -I /usr/include/c++/4.5 -c sort.cpp
g++ -D DEBUG -g -Wall -I /usr/include/c++/4.5 main.cpp sort.o -o sort_testing.bin
/tmp/ccRl2ZvH.o: In function `main':
/home/dev/c++/sorting/main.cpp:33: undefined reference to `void sort::swap<int>;(int*, int, int)'
collect2: ld returned 1 exit status
make: *** [debug] Error 1

知道如何解决此问题吗?

3 个答案:

答案 0 :(得分:1)

模板定义需要在使用点可见(以便可以隐式实例化) OR 您需要显式实例化它们(在这种情况下,链接器将带来显式实例化和一起使用)。

在你的情况下,我会选择一个(和隐式实例化)。这意味着您需要将(模板的)模板定义移动到头文件中:

// sort.hpp
#ifndef SORT_H
#define SORT_H

namespace sort{
    template<class T>
    void swap(T*,int,int)
    {
        T t = items[index_a];
        items[index_a] = items[index_b];
        items[index_b] = t;
    }
}

#endif

或者(但在一般情况下不太有用(但有其用途))是显式模板实例化。在这里,您可以在sort.cpp中定义要定义的模板的哪些变体。

// sort.cpp
#include "sort.hpp"

namespace sort{
    template<class T>
        void swap(T* items, int index_a, int index_b){
            T t = items[index_a];
            items[index_a] = items[index_b];
            items[index_b] = t;
        }

    // Define an explicit function template instantiation.
    // Here we define that the integer version of the template must exist.
    template void swap<int>(int*,int,int);
}

当您想限制模板的版本数量时,这非常有用。

答案 1 :(得分:0)

模板定义必须位于同一文件中。因此,在头文件本身中定义函数。

或者将.cpp文件包含在底部的标题中:

// sort.hpp
#ifndef SORT_H
#define SORT_H

namespace sort{
    template<class T> void swap(T*,int,int);
}


#include "sort.cpp" //<--------------- this!

#endif

答案 2 :(得分:0)

您无法在.cpp文件中定义模板。 swap的定义应仅在sort.hpp文件中。有关详细信息,请参阅此常见问题解答Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?