【问题标题】:cannot find constructor in C++ templated code [duplicate]在 C++ 模板代码中找不到构造函数 [重复]
【发布时间】:2013-07-30 15:57:24
【问题描述】:

编译时出现此错误:g++ main.cpp Vec.cpp -Wall -o main -I。

/tmp/cciqbEQJ.o: In function `main':
main.cpp:(.text+0x8b): undefined reference to `Vec<double>::Vec()'
main.cpp:(.text+0x9b): undefined reference to `Vec<double>::~Vec()'
collect2: ld returned 1 exit status
make: *** [all] Error 1

我不明白,因为我之前做过很多多源文件程序,我从来没有遇到过找不到构造函数的错误。似乎编译器无法将模板代码动态绑定到模板的实例化。另外,我在 .h 文件上放了一个宏保护,但它没有在下面显示。

源码如下:

Vec.cpp

#include "Vec.h"

using namespace std;

template<class T>
Vec<T>::Vec() {
   create();
}


template<class T>
Vec<T>::Vec( size_type n, const value_type& t ){
        create(n,t);
}
template<class T>
Vec<T>::Vec(const Vec& v)
{
        create(v.begin(), v.end());
}

template<class T>
Vec<T>::~Vec(){
    uncreate();
}

   template<class T>
   void Vec<T>::create()
{
 data = avail = limit = 0;
}

   template<class T>
   void Vec<T>::create(size_type n, const T& val)
{
  data = alloc.allocate(n);
  limit = avail = data + n;
  uninitialized_fill(data,limit, val);
}

template<class T>
void Vec<T>::create(const_iterator i, const_iterator j) {

    data = alloc.allocate(j-i);
    limit = avail = uninitialized_copy(i, j, data);
}
    template<class T> 
    void Vec<T>::uncreate() {

            if (data) {

                    iterator it = avail;
                    while (it != data)
                            alloc.destroy(--it);

                    alloc.deallocate(data,limit-data);
            }
            data = limit = avail =0;
    }

    template<class T> void Vec<T>::grow() {
            size_type new_size = max ( 2 * (limit-data), ptrdiff_t(1));

            iterator new_data = alloc.allocate(new_size);
            iterator new_avail = unitialized_copy(data, avail, new_data);

            uncreate();
            data = new_data;
            avail = new_avail;
            limit = data + new_size;

    }


    template<class T> void Vec<T>::unchecked_append(const T& val) {
            alloc.construct(avail++, val);
    }

    template<class T>
    void Vec<T>::push_back(const T& t){
                    if ( avail == limit )
                            grow();

                    unchecked_append(t);
    }

Vec.h

    template<class T> class Vec{
    public:
            typedef T* iterator;
            typedef const T* const_iterator;
            typedef size_t size_type;
            typedef T value_type;

            Vec();
            Vec( size_type n, const T& t=T() );

            Vec(const Vec& v);
            Vec& operator=(const Vec& v);

            ~Vec();
            void push_back(const T& t);

            inline size_type size() const { return limit - data; }

            inline iterator begin() {return data;}
            inline const_iterator begin() const { return data; }

            inline iterator end() { return limit; }
            inline const_iterator end() const { return limit; }

            inline T& operator[](size_type i){
                    return data[i];
            }
            const T& operator[](size_type i) const { return data[i]; }


    private:
            iterator data;
            iterator limit;
            iterator avail;

            //facilities for memory allocation
            allocator<T> alloc;

            //allocate and initialize the underlying array
            void create();
            void create(size_type, const T&);
            void create(const_iterator, const_iterator);

            //destroy the elements in the array and free the memory
            void uncreate();

            //support functions for push_back
        void grow();
        void unchecked_append(const T&);
};

main.cpp

 int main(void) {
   Vec<double> test;
 }             

【问题讨论】:

  • 你不能把这样的模板放在 CPP 文件中
  • 不要在*.cpp中使用模板。
  • 否则应该如何在 .cpp 中定义任何内容?没有模板编译器会抛出“T is undefined”

标签: c++ oop templates constructor


【解决方案1】:

为了让编译器生成代码,它必须同时查看模板定义和用于模板的特定类型。

所以,在main.cpp 中,只需在顶部处添加#include "Vec.cpp"

编译使用 g++ main.cpp -Wall -o main -I. Vec.cpp 现已删除。

这将确保在编译过程中模板声明和实现是在一起的,同时实现仍然与声明分开。

另一种选择是在 Vec.hend 处包含此 .cpp,如 juanchopanza 的上述评论链接中所建议的那样

更多详情请参考:-Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file ?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 2011-05-24
    • 2018-04-13
    相关资源
    最近更新 更多