Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't link a template function

Tags:

c++

templates

I have this code:

template<typename T>
class Listoid{

  private:
    std::vector<T> list;

  public:
    typedef typename std::vector<T>::iterator iterator;

    iterator begin() {return list.begin();}
    iterator end() {return list.end();}

  public:
    Listoid(T t) {
      list.push_back(t);
    }

  const T operator [](int i){
    return list[i];
  }

  void addElem(T ne){
    list.push_back(ne);
  }

  friend T cons(T new_elem, Listoid<T> list);

};

template<typename T>
Listoid<T> cons(T new_elem, Listoid<T> list){

  Listoid<T> new_list(new_elem);
  for(typename Listoid<T>::iterator it = list.begin(), e = list.end();
        it != e; ++it){
          new_list.addElem(*it);
        }
  return new_list;
}


int main(){

  Listoid<int> lista(312);
  lista.addElem(22);

  Listoid<int> lista2 = cons(21, lista);

  return EXIT_SUCCESS;
}

But i cannot compile it; i get the following error:

/tmp/listoid-3kYCmd.o: In function `main':
listoid.cpp:(.text+0xda): undefined reference to `cons(int, Listoid<int>)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Maybe it's really simple, but i cannot solve it. Can someone help?

like image 230
Aslan986 Avatar asked Jun 28 '26 23:06

Aslan986


2 Answers

You must tell the compiler that cons is function template not simple function. Use this syntax:

friend T cons <>(T new_elem, Listoid<T> list);

Note <> after function name.

Otherwise it is searching for simple function, not function template. That is linker telling you.

[UPDATE]

And do not forget to add forward declaration of your function before its friend class, so your class will know what is the friend.

template<typename T>
Listoid<T> cons(T new_elem, Listoid<T> list);

[UPDATE2]

And change your type of your function template, and add forward declaration of your class. See:

template<typename T>
class Listoid;
template<typename T>
Listoid<T> cons(T new_elem, Listoid<T> list);

template<typename T>
class Listoid{
...

  friend Listoid<T> cons <>(T new_elem, Listoid<T> list);

};

That works for me: ideone

like image 140
PiotrNycz Avatar answered Jun 30 '26 15:06

PiotrNycz


friend T cons(T new_elem, Listoid<T> list); is not a template, your later template<typename T> Listoid<T> cons(T new_elem, Listoid<T> list) is different overload of the cons() function. See FAQ.

like image 42
wilx Avatar answered Jun 30 '26 15:06

wilx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!