Compiler cannot find instantiation of templated method [duplicate]












0
















This question already has an answer here:




  • Why can templates only be implemented in the header file?

    14 answers



  • What is an undefined reference/unresolved external symbol error and how do I fix it?

    32 answers




I'm trying to write a method for a selection class that I've written that scans though the selection list for the first item that can be cast to a given datatype and returns it (or null if there is none). Unfortunately, my compiler is complaining:



error: undefined reference to `GraphNode* Selection::getFirstItem<GraphNode*>()'


The editor is providing some hints:



warning: instantiation of function 'Selection::getFirstItem<GraphNode *>' required here, but no definition is available
forward declaration of template entity is here
add an explicit instantiation declaration to suppress this warning if 'Selection::getFirstItem<GraphNode *>' is explicitly instantiated in another translation unit


Here is the relevant part of my selection class:



//Selection.h
class Selection : public QObject
{
QList<QObject*> _items;
public:

template <class T> T getLastItem();
}

//Selection.cpp
template <class T> T Selection::getLastItem()
{
for (QObject* obj: _items)
{
T val = qobject_cast<T>(obj);
if (val)
return val;
}
return nullptr;
}


And this is the line where the error occurs:



GraphNode* top = _curScene->selection().getLastItem<GraphNode*>();


Is there a way to write this so that the compiler is able to find the implementation of my getLastItem() method?










share|improve this question















marked as duplicate by Matthieu Brucher, n.m. c++
Users with the  c++ badge can single-handedly close c++ questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 24 '18 at 11:16


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.























    0
















    This question already has an answer here:




    • Why can templates only be implemented in the header file?

      14 answers



    • What is an undefined reference/unresolved external symbol error and how do I fix it?

      32 answers




    I'm trying to write a method for a selection class that I've written that scans though the selection list for the first item that can be cast to a given datatype and returns it (or null if there is none). Unfortunately, my compiler is complaining:



    error: undefined reference to `GraphNode* Selection::getFirstItem<GraphNode*>()'


    The editor is providing some hints:



    warning: instantiation of function 'Selection::getFirstItem<GraphNode *>' required here, but no definition is available
    forward declaration of template entity is here
    add an explicit instantiation declaration to suppress this warning if 'Selection::getFirstItem<GraphNode *>' is explicitly instantiated in another translation unit


    Here is the relevant part of my selection class:



    //Selection.h
    class Selection : public QObject
    {
    QList<QObject*> _items;
    public:

    template <class T> T getLastItem();
    }

    //Selection.cpp
    template <class T> T Selection::getLastItem()
    {
    for (QObject* obj: _items)
    {
    T val = qobject_cast<T>(obj);
    if (val)
    return val;
    }
    return nullptr;
    }


    And this is the line where the error occurs:



    GraphNode* top = _curScene->selection().getLastItem<GraphNode*>();


    Is there a way to write this so that the compiler is able to find the implementation of my getLastItem() method?










    share|improve this question















    marked as duplicate by Matthieu Brucher, n.m. c++
    Users with the  c++ badge can single-handedly close c++ questions as duplicates and reopen them as needed.

    StackExchange.ready(function() {
    if (StackExchange.options.isMobile) return;

    $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
    var $hover = $(this).addClass('hover-bound'),
    $msg = $hover.siblings('.dupe-hammer-message');

    $hover.hover(
    function() {
    $hover.showInfoMessage('', {
    messageElement: $msg.clone().show(),
    transient: false,
    position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
    dismissable: false,
    relativeToBody: true
    });
    },
    function() {
    StackExchange.helpers.removeMessages();
    }
    );
    });
    });
    Nov 24 '18 at 11:16


    This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.





















      0












      0








      0









      This question already has an answer here:




      • Why can templates only be implemented in the header file?

        14 answers



      • What is an undefined reference/unresolved external symbol error and how do I fix it?

        32 answers




      I'm trying to write a method for a selection class that I've written that scans though the selection list for the first item that can be cast to a given datatype and returns it (or null if there is none). Unfortunately, my compiler is complaining:



      error: undefined reference to `GraphNode* Selection::getFirstItem<GraphNode*>()'


      The editor is providing some hints:



      warning: instantiation of function 'Selection::getFirstItem<GraphNode *>' required here, but no definition is available
      forward declaration of template entity is here
      add an explicit instantiation declaration to suppress this warning if 'Selection::getFirstItem<GraphNode *>' is explicitly instantiated in another translation unit


      Here is the relevant part of my selection class:



      //Selection.h
      class Selection : public QObject
      {
      QList<QObject*> _items;
      public:

      template <class T> T getLastItem();
      }

      //Selection.cpp
      template <class T> T Selection::getLastItem()
      {
      for (QObject* obj: _items)
      {
      T val = qobject_cast<T>(obj);
      if (val)
      return val;
      }
      return nullptr;
      }


      And this is the line where the error occurs:



      GraphNode* top = _curScene->selection().getLastItem<GraphNode*>();


      Is there a way to write this so that the compiler is able to find the implementation of my getLastItem() method?










      share|improve this question

















      This question already has an answer here:




      • Why can templates only be implemented in the header file?

        14 answers



      • What is an undefined reference/unresolved external symbol error and how do I fix it?

        32 answers




      I'm trying to write a method for a selection class that I've written that scans though the selection list for the first item that can be cast to a given datatype and returns it (or null if there is none). Unfortunately, my compiler is complaining:



      error: undefined reference to `GraphNode* Selection::getFirstItem<GraphNode*>()'


      The editor is providing some hints:



      warning: instantiation of function 'Selection::getFirstItem<GraphNode *>' required here, but no definition is available
      forward declaration of template entity is here
      add an explicit instantiation declaration to suppress this warning if 'Selection::getFirstItem<GraphNode *>' is explicitly instantiated in another translation unit


      Here is the relevant part of my selection class:



      //Selection.h
      class Selection : public QObject
      {
      QList<QObject*> _items;
      public:

      template <class T> T getLastItem();
      }

      //Selection.cpp
      template <class T> T Selection::getLastItem()
      {
      for (QObject* obj: _items)
      {
      T val = qobject_cast<T>(obj);
      if (val)
      return val;
      }
      return nullptr;
      }


      And this is the line where the error occurs:



      GraphNode* top = _curScene->selection().getLastItem<GraphNode*>();


      Is there a way to write this so that the compiler is able to find the implementation of my getLastItem() method?





      This question already has an answer here:




      • Why can templates only be implemented in the header file?

        14 answers



      • What is an undefined reference/unresolved external symbol error and how do I fix it?

        32 answers








      c++ qt






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 24 '18 at 11:15







      kitfox

















      asked Nov 24 '18 at 11:05









      kitfoxkitfox

      5001418




      5001418




      marked as duplicate by Matthieu Brucher, n.m. c++
      Users with the  c++ badge can single-handedly close c++ questions as duplicates and reopen them as needed.

      StackExchange.ready(function() {
      if (StackExchange.options.isMobile) return;

      $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
      var $hover = $(this).addClass('hover-bound'),
      $msg = $hover.siblings('.dupe-hammer-message');

      $hover.hover(
      function() {
      $hover.showInfoMessage('', {
      messageElement: $msg.clone().show(),
      transient: false,
      position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
      dismissable: false,
      relativeToBody: true
      });
      },
      function() {
      StackExchange.helpers.removeMessages();
      }
      );
      });
      });
      Nov 24 '18 at 11:16


      This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









      marked as duplicate by Matthieu Brucher, n.m. c++
      Users with the  c++ badge can single-handedly close c++ questions as duplicates and reopen them as needed.

      StackExchange.ready(function() {
      if (StackExchange.options.isMobile) return;

      $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
      var $hover = $(this).addClass('hover-bound'),
      $msg = $hover.siblings('.dupe-hammer-message');

      $hover.hover(
      function() {
      $hover.showInfoMessage('', {
      messageElement: $msg.clone().show(),
      transient: false,
      position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
      dismissable: false,
      relativeToBody: true
      });
      },
      function() {
      StackExchange.helpers.removeMessages();
      }
      );
      });
      });
      Nov 24 '18 at 11:16


      This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


























          0






          active

          oldest

          votes

















          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes

          Popular posts from this blog

          Create new schema in PostgreSQL using DBeaver

          Deepest pit of an array with Javascript: test on Codility

          Costa Masnaga