无法在C ++模板代码中找到构造函数 [英] cannot find constructor in C++ templated code

查看:180
本文介绍了无法在C ++模板代码中找到构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在编译时遇到此错误:g ++ main.cpp Vec.cpp -Wall -o main -I。

I am getting this error when compiling it with: 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

我不明白,因为我之前做了很多多源文件程序,这个错误,其中没有找到构造函数。看起来编译器不能动态地将模板代码绑定到模板的实例化。

I don't understand because I have done a lot of multiple-source file programs before and I never got this error where the constructor is not found. It seems like the compiler is not able to dynamically bind the template code to the instantiation of the template. Also, I have put a macro guard on the .h file but it is not shown below.

源代码如下:

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;
 }             


推荐答案

生成代码,它必须同时看到模板定义和用于模板的特定类型。

In order for the compiler to generate the code, it must see both the template definition and the specific types used to for the template.

所以,在 main.cpp 添加行只是 #includeVec.cpp

So, in main.cpp add line just #include "Vec.cpp" at the top.

使用
编译 g ++ main.cpp - 现在已删除。

Compile using g++ main.cpp -Wall -o main -I. <-- Notice Vec.cpp removed now.

这将确保模板声明和实现在编译期间在一起,同时实现仍然与声明分离。

This will make sure the template declaration and implementation are together during compilation, at same time implementation is still separated from declaration.

另一个替代方法是包含此<在结束 Vec.h by juanchopanza

Another alternative is to include this .cpp while at the end of Vec.h as suggested in the above commented link of SO by juanchopanza

更多详情参考: - 为什么我不能将我的模板类的定义和它的声明分开并放在一个.cpp文件?

For more details Ref :- Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file ?

这篇关于无法在C ++模板代码中找到构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆