【问题标题】:c++ templated class does not linkc++模板类不链接
【发布时间】:2010-12-16 07:41:06
【问题描述】:
template<typename AT>
class growVector {

        int size;
        AT **arr;
        AT* defaultVal;

    public:

        growVector(int size , AT* defaultVal);   //Expects number of elements (5) and default value (NULL)
        AT*& operator[](unsigned pos);
        int length();
        void reset(int pos);    //Resets an element to default value
        void reset();           //Resets all elements to default value
        ~growVector();
};

而 .cpp 是

template<typename AT>
growVector<AT>::growVector(int size, AT* defaultVal) {
    arr = new AT*[size];
    this->size = size;
    for (int i = 0 ; i < size; i++){
        arr[i] = defaultVal;
    }
}

template<typename AT>
AT*& growVector<AT>::operator [](unsigned pos){
    if (pos >= size){
        int newSize = size*2;
        AT** newArr = new AT*[newSize];
        memcpy(newArr, arr, sizeof(AT)*size);
        for (int i = size; i<newSize; i++)
            newArr[i] = defaultVal;
        size = newSize;
        delete arr;
        arr = newArr;
    }
    return arr[pos];
}

//template<typename AT>
//const AT*& growVector<AT>::operator [](unsigned pos) const{
//  if (pos >= size)
//      throw std::range_error("index out of range in constant vector");
//  }
//  return NULL;
//}
template<typename AT>
int growVector<AT>::length(){
    return size;
}

template<typename AT>
growVector<AT>::~growVector(){
    delete arr;
}

template<typename AT>
void growVector<AT>::reset(int pos){
    if (pos>=size)
        throw new std::range_error("index out of bounds");
    arr[pos] = defaultVal;
}

template<typename AT>
void growVector<AT>::reset(){
    for (int pos = 0; pos<size; pos++)
        arr[pos] = defaultVal;
}

...非常基础。

我用在

int main() {

    growVector<char> gv(5, (char*)NULL);
    char* x = NULL;
    for (int i = 0; i< 50; i++){
        gv[i] = x;
    }
    gv.reset();
    return 0;
}

它编译但链接器说:

Invoking: GCC C++ Linker
g++ -pthread -o"base"  ./src/base.o  ./src/base/baseController.o ./src/base/baseThreads.o ./src/base/utils.o  ./src/base/utils/utilClasses.o   
./src/base.o: In function `main':
/home/dario/workspace/base/Debug/../src/base.cpp:95: undefined reference to `baseUtils::growVector<char>::growVector(int, char*)'
/home/dario/workspace/base/Debug/../src/base.cpp:98: undefined reference to `baseUtils::growVector<char>::operator[](unsigned int)'
/home/dario/workspace/base/Debug/../src/base.cpp:100: undefined reference to `baseUtils::growVector<char>::reset()'
/home/dario/workspace/base/Debug/../src/base.cpp:101: undefined reference to `baseUtils::growVector<char>::~growVector()'
/home/dario/workspace/base/Debug/../src/base.cpp:101: undefined reference to `baseUtils::growVector<char>::~growVector()'
collect2: ld returned 1 exit status

我真的一无所知

【问题讨论】:

标签: c++ templates linker


【解决方案1】:

对于模板,一般来说,定义应该放在头文件中,因为它是所有编译单元都需要的。

当您知道将使用哪些类型调用您的模板类时,有一些技巧可以避免这样做,但对于真正通用的问题,它就是行不通的。

注意

如果我是你,我会使用 STL 容器,结果不太可能出现错误。

【讨论】:

    【解决方案2】:

    尝试将定义也放在头文件中。详情可以阅读this FAQ

    【讨论】:

      【解决方案3】:

      小故事:您需要将模板的整个实现放在标题中。

      理论上,C++ 有一个关键字(“export”),允许您像其他代码一样分隔模板(标题中的声明,.cpp 文件中的主体)。不幸的是,只有一个编译器(Comeau C++)实现了 export 关键字,所以这个选项对大多数人不可用。我相信如果您使用一个或两个未记录的开关,英特尔 C++ 也在一定程度上实现了 export 关键字,但它不受支持,因此它是否真的可靠工作可能会有疑问(我确信解析部分确实如此) ,但如果其他部分出现问题,我不会感到惊讶)。

      【讨论】:

        【解决方案4】:

        编译器需要同时查看声明和定义才能实例化模板。由于您确实在 .cpp 中提供了 growVector 的显式实例化/特化,因此编译器无法为您生成实例化模板。这是您会发现模板类倾向于在头文件范围内声明和定义的主要原因之一。

        您通常可以依靠足够智能的现代链接器来删除同一模板的重复实例化,但它们不一定能够实例化模板。

        【讨论】:

          【解决方案5】:

          您是否遗漏了对 baseUtils 命名空间的引用?

          /home/dario/workspace/base/Debug/../src/base.cpp:95: undefined reference to `baseUtils::growVector<char>::growVector(int, char*)'
          

          我没有在您的 main() 代码中看到它,并且您的类定义没有从任何其他类继承。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多