templates and g++

This is a discussion on templates and g++ within the C++ Programming forums, part of the General Programming Boards category; For the following code template_eg.cc: Code: template<typename T> class MyArray { public: MyArray(); MyArray(MyArray& copy); MyArray& operator=(MyArray& copy); }; class ...

  1. #1
    Spam is Good
    Join Date
    Jan 2009
    Location
    In a cave on Mars
    Posts
    37

    templates and g++

    For the following code template_eg.cc:

    Code:
    template<typename T>
    class MyArray
    {
    public:
      MyArray();
      MyArray(MyArray& copy);
      MyArray& operator=(MyArray& copy);
    };
    
    class MyData
    {
    public:
      MyData(MyArray<int>& x, MyArray<int>& y);
      const MyArray<int>& x();
      const MyArray<int>& y();
    };
    
    MyArray<int> read_data(int*, char**);
    void make_changes(MyData* edit);
    
    int main(int argc, char* argv[])
    {
      const MyArray<int> read_x = read_data(&argc, argv);
      const MyArray<int> read_y = read_data(&argc, argv);
    
      MyData user_data(read_x, read_y);
      MyData edit_buffer(user_data);
      make_changes(&edit_buffer);
    }
    Why when I complie I get the following errors:
    Code:
    coletek@spamisgood:~/sandbox/cc> g++ template_eg.cc -o template_eg
    template_eg.cc: In function ‘int main(int, char**)’:
    template_eg.cc:23: error: no matching function for call to ‘MyArray<int>::MyArray(MyArray<int>)’
    template_eg.cc:6: note: candidates are: MyArray<T>::MyArray(MyArray<T>&) [with T = int]
    template_eg.cc:24: error: no matching function for call to ‘MyArray<int>::MyArray(MyArray<int>)’
    template_eg.cc:6: note: candidates are: MyArray<T>::MyArray(MyArray<T>&) [with T = int]
    template_eg.cc:26: error: no matching function for call to ‘MyData::MyData(const MyArray<int>&, const MyArray<int>&)’
    template_eg.cc:13: note: candidates are: MyData::MyData(MyArray<int>&, MyArray<int>&)
    template_eg.cc:11: note:                 MyData::MyData(const MyData&)
    I new to using templates. Thx.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    So the line
    Code:
    const MyArray<int> read_x = read_data(&argc, argv);
    calls the copy constructor -- you have a temporary MyArray<int> over there on the right. So you should make a copy constructor that works with a temporary object. Hint: that would like
    Code:
    MyArray(const MyArray &array_to_be_copied);

  3. #3
    Spam is Good
    Join Date
    Jan 2009
    Location
    In a cave on Mars
    Posts
    37
    Ok, some fix is:

    Code:
    MyData(MyArray<int>& x, MyArray<int>& y);
    should be

    Code:
    MyData(const MyArray<int>& x, const MyArray<int>& y);
    for const-correctness, however still can't fix the "no matching function for call to ..." errors. Any ideas people?
    "What comes around, goes around"

  4. #4
    Spam is Good
    Join Date
    Jan 2009
    Location
    In a cave on Mars
    Posts
    37
    Ok, so after fixing the code to:

    Code:
    template<typename T>
    class MyArray
    {
    public:
      MyArray();
      //MyArray(MyArray& copy);                                               
      MyArray(const MyArray& copy);
      MyArray& operator=(MyArray& copy);
    };
    
    class MyData
    {
    public:
      //MyData(MyArray<int>& x, MyArray<int>& y);                                   
      MyData(const MyArray<int>& x, const MyArray<int>& y);
      const MyArray<int>& x();
      const MyArray<int>& y();
    };
    
    MyArray<int> read_data(int*, char**);
    void make_changes(MyData* edit);
    
    int main(int argc, char* argv[])
    {
      const MyArray<int> read_x = read_data(&argc, argv);
      const MyArray<int> read_y = read_data(&argc, argv);
    
      MyData user_data(read_x, read_y);
      MyData edit_buffer(user_data);
      make_changes(&edit_buffer);
    }
    I'm now getting:

    Code:
    coletek@spamisgood:~/sandbox/cc> g++ template_eg.cc -o template_eg
    /tmp/ccwMgmQo.o: In function `main':
    template_eg.cc:(.text+0x30): undefined reference to `read_data(int*, char**)'
    template_eg.cc:(.text+0x48): undefined reference to `read_data(int*, char**)'
    template_eg.cc:(.text+0x64): undefined reference to `MyData::MyData(MyArray<int> const&, MyArray<int> const&)'
    template_eg.cc:(.text+0x70): undefined reference to `make_changes(MyData*)'
    collect2: ld returned 1 exit status
    Arrr... where I'm I going wrong?
    "What comes around, goes around"

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by coletek View Post
    Ok, some fix is:

    Code:
    MyData(MyArray<int>& x, MyArray<int>& y);
    should be

    Code:
    MyData(const MyArray<int>& x, const MyArray<int>& y);
    for const-correctness, however still can't fix the "no matching function for call to ..." errors. Any ideas people?
    That bears no resemblance to my hint, so it doesn't surprise me that it doesn't do anything to help. I see that you got it down below, though.
    Quote Originally Posted by coletek View Post
    Ok, so after fixing the code to:

    Code:
    template<typename T>
    class MyArray
    {
    public:
      MyArray();
      //MyArray(MyArray& copy);                                               
      MyArray(const MyArray& copy);
      MyArray& operator=(MyArray& copy);
    };
    
    class MyData
    {
    public:
      //MyData(MyArray<int>& x, MyArray<int>& y);                                   
      MyData(const MyArray<int>& x, const MyArray<int>& y);
      const MyArray<int>& x();
      const MyArray<int>& y();
    };
    
    MyArray<int> read_data(int*, char**);
    void make_changes(MyData* edit);
    
    int main(int argc, char* argv[])
    {
      const MyArray<int> read_x = read_data(&argc, argv);
      const MyArray<int> read_y = read_data(&argc, argv);
    
      MyData user_data(read_x, read_y);
      MyData edit_buffer(user_data);
      make_changes(&edit_buffer);
    }
    I'm now getting:

    Code:
    coletek@spamisgood:~/sandbox/cc> g++ template_eg.cc -o template_eg
    /tmp/ccwMgmQo.o: In function `main':
    template_eg.cc:(.text+0x30): undefined reference to `read_data(int*, char**)'
    template_eg.cc:(.text+0x48): undefined reference to `read_data(int*, char**)'
    template_eg.cc:(.text+0x64): undefined reference to `MyData::MyData(MyArray<int> const&, MyArray<int> const&)'
    template_eg.cc:(.text+0x70): undefined reference to `make_changes(MyData*)'
    collect2: ld returned 1 exit status
    Arrr... where I'm I going wrong?
    I agree with your compiler: you do not, after all, have a function called read_data or make_changes. Just declaring the function name is not enough, but you need to actually write the functions themselves.

  6. #6
    Spam is Good
    Join Date
    Jan 2009
    Location
    In a cave on Mars
    Posts
    37
    Of course, now complies with:

    Code:
    template<typename T>
    class MyArray
    {
    public:
      MyArray();
      //MyArray(MyArray& copy);                                               
      MyArray(const MyArray& copy);
      MyArray& operator=(MyArray& copy);
    };
    
    class MyData
    {
    public:
      //MyData(MyArray<int>& x, MyArray<int>& y);                                   
      MyData(const MyArray<int>& x, const MyArray<int>& y) {};
      const MyArray<int>& x();
      const MyArray<int>& y();
    };
    
    //MyArray<int> read_data(int*, char**);
    //void make_changes(MyData* edit);
    MyArray<int> read_data(int*, char**) {};
    void make_changes(MyData* edit) {};
    
    int main(int argc, char* argv[])
    {
      const MyArray<int> read_x = read_data(&argc, argv);
      const MyArray<int> read_y = read_data(&argc, argv);
    
      MyData user_data(read_x, read_y);
      MyData edit_buffer(user_data);
      make_changes(&edit_buffer);
    }
    "What comes around, goes around"

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    But only because G++ is so lenient regarding return values. After all, read_data claims to return a MyArray<int> but returns nothing! This is most definitely undefined.

    Tip: if you just want to make certain that code is semantically correct, but don't want to provide all implementations, you can use the -fsyntax-only switch to G++. In this mode, the compiler checks that your code is valid and that all templates can be instantiated, but it doesn't produce any output or try to link the file.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Spam is Good
    Join Date
    Jan 2009
    Location
    In a cave on Mars
    Posts
    37
    Quote Originally Posted by CornedBee
    But only because G++ is so lenient regarding return values.
    I've notice g++ is lenient on a few things, any idea why that is?
    "What comes around, goes around"

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Because it has to cope with endless amounts of legacy code.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21