Simple template class with overloaded << operator fails, “Invalid use of template-id”












0















I'm trying to overload the stream output operator for a template class of mine. I've been running into all sorts of trouble with undefined references and now the error



"invalid use of template-id 'operator<< <>' in declaration of primary template"


I've read every Stackoverflow and other forum post i could find on the correct declaration, and there seem to be multiple ways people manage my desired result. Could anyone please help me understand what is going wrong?



The .h file:



//class must be forward declared because it contains a friend function template
template<class T> class messageTemplate;

//friend function also must be forwards declared
template<class A> std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

template <class T>
class messageTemplate {
public:
messageTemplate(const std::string &topic, T data);

template <class A>
friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);

private:
std::string topic;
T data;
};


the .cpp:



template class messageTemplate<int>;
template class messageTemplate<double>;
template class messageTemplate<std::string>;
template class messageTemplate<bool>;

template<class T>
messageTemplate<T>::messageTemplate(const std::string &topic, T data):topic(topic), data(data) {};

template <class T>
std::ostream &operator<< (std::ostream &os, messageTemplate<T> &aTemplate) {
os << "topic: " << aTemplate.topic << " data: " << aTemplate.data;
return os;
};


At this point i've tried and applied so many solutions I feel like starting from scratch might be better.



Full error message (happens at the declaration in het .h file):




error: invalid use of template-id 'operator<< <>' in declaration of
primary template
friend std::ostream &operator<< <>(std::ostream &os, messageTemplate &aTemplate);











share|improve this question


















  • 3





    friend std::ostream &operator<< **<>**(std::ostream &os, messageTemplate<A> &aTemplate); Where did you read that you should use the "<>" part?

    – Daniel
    Jan 18 at 23:35






  • 1





    You need to remove <> from friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);

    – Remy Lebeau
    Jan 18 at 23:36













  • Probably don't need to forward declare either the class or friend func

    – Phil M
    Jan 18 at 23:42











  • @Daniel Here: daniweb.com/programming/software-development/threads/65196/… , seemed to make sense to me :(

    – Stef
    Jan 19 at 14:28
















0















I'm trying to overload the stream output operator for a template class of mine. I've been running into all sorts of trouble with undefined references and now the error



"invalid use of template-id 'operator<< <>' in declaration of primary template"


I've read every Stackoverflow and other forum post i could find on the correct declaration, and there seem to be multiple ways people manage my desired result. Could anyone please help me understand what is going wrong?



The .h file:



//class must be forward declared because it contains a friend function template
template<class T> class messageTemplate;

//friend function also must be forwards declared
template<class A> std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

template <class T>
class messageTemplate {
public:
messageTemplate(const std::string &topic, T data);

template <class A>
friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);

private:
std::string topic;
T data;
};


the .cpp:



template class messageTemplate<int>;
template class messageTemplate<double>;
template class messageTemplate<std::string>;
template class messageTemplate<bool>;

template<class T>
messageTemplate<T>::messageTemplate(const std::string &topic, T data):topic(topic), data(data) {};

template <class T>
std::ostream &operator<< (std::ostream &os, messageTemplate<T> &aTemplate) {
os << "topic: " << aTemplate.topic << " data: " << aTemplate.data;
return os;
};


At this point i've tried and applied so many solutions I feel like starting from scratch might be better.



Full error message (happens at the declaration in het .h file):




error: invalid use of template-id 'operator<< <>' in declaration of
primary template
friend std::ostream &operator<< <>(std::ostream &os, messageTemplate &aTemplate);











share|improve this question


















  • 3





    friend std::ostream &operator<< **<>**(std::ostream &os, messageTemplate<A> &aTemplate); Where did you read that you should use the "<>" part?

    – Daniel
    Jan 18 at 23:35






  • 1





    You need to remove <> from friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);

    – Remy Lebeau
    Jan 18 at 23:36













  • Probably don't need to forward declare either the class or friend func

    – Phil M
    Jan 18 at 23:42











  • @Daniel Here: daniweb.com/programming/software-development/threads/65196/… , seemed to make sense to me :(

    – Stef
    Jan 19 at 14:28














0












0








0








I'm trying to overload the stream output operator for a template class of mine. I've been running into all sorts of trouble with undefined references and now the error



"invalid use of template-id 'operator<< <>' in declaration of primary template"


I've read every Stackoverflow and other forum post i could find on the correct declaration, and there seem to be multiple ways people manage my desired result. Could anyone please help me understand what is going wrong?



The .h file:



//class must be forward declared because it contains a friend function template
template<class T> class messageTemplate;

//friend function also must be forwards declared
template<class A> std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

template <class T>
class messageTemplate {
public:
messageTemplate(const std::string &topic, T data);

template <class A>
friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);

private:
std::string topic;
T data;
};


the .cpp:



template class messageTemplate<int>;
template class messageTemplate<double>;
template class messageTemplate<std::string>;
template class messageTemplate<bool>;

template<class T>
messageTemplate<T>::messageTemplate(const std::string &topic, T data):topic(topic), data(data) {};

template <class T>
std::ostream &operator<< (std::ostream &os, messageTemplate<T> &aTemplate) {
os << "topic: " << aTemplate.topic << " data: " << aTemplate.data;
return os;
};


At this point i've tried and applied so many solutions I feel like starting from scratch might be better.



Full error message (happens at the declaration in het .h file):




error: invalid use of template-id 'operator<< <>' in declaration of
primary template
friend std::ostream &operator<< <>(std::ostream &os, messageTemplate &aTemplate);











share|improve this question














I'm trying to overload the stream output operator for a template class of mine. I've been running into all sorts of trouble with undefined references and now the error



"invalid use of template-id 'operator<< <>' in declaration of primary template"


I've read every Stackoverflow and other forum post i could find on the correct declaration, and there seem to be multiple ways people manage my desired result. Could anyone please help me understand what is going wrong?



The .h file:



//class must be forward declared because it contains a friend function template
template<class T> class messageTemplate;

//friend function also must be forwards declared
template<class A> std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

template <class T>
class messageTemplate {
public:
messageTemplate(const std::string &topic, T data);

template <class A>
friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);

private:
std::string topic;
T data;
};


the .cpp:



template class messageTemplate<int>;
template class messageTemplate<double>;
template class messageTemplate<std::string>;
template class messageTemplate<bool>;

template<class T>
messageTemplate<T>::messageTemplate(const std::string &topic, T data):topic(topic), data(data) {};

template <class T>
std::ostream &operator<< (std::ostream &os, messageTemplate<T> &aTemplate) {
os << "topic: " << aTemplate.topic << " data: " << aTemplate.data;
return os;
};


At this point i've tried and applied so many solutions I feel like starting from scratch might be better.



Full error message (happens at the declaration in het .h file):




error: invalid use of template-id 'operator<< <>' in declaration of
primary template
friend std::ostream &operator<< <>(std::ostream &os, messageTemplate &aTemplate);








c++ templates operator-overloading






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 18 at 23:32









StefStef

31




31








  • 3





    friend std::ostream &operator<< **<>**(std::ostream &os, messageTemplate<A> &aTemplate); Where did you read that you should use the "<>" part?

    – Daniel
    Jan 18 at 23:35






  • 1





    You need to remove <> from friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);

    – Remy Lebeau
    Jan 18 at 23:36













  • Probably don't need to forward declare either the class or friend func

    – Phil M
    Jan 18 at 23:42











  • @Daniel Here: daniweb.com/programming/software-development/threads/65196/… , seemed to make sense to me :(

    – Stef
    Jan 19 at 14:28














  • 3





    friend std::ostream &operator<< **<>**(std::ostream &os, messageTemplate<A> &aTemplate); Where did you read that you should use the "<>" part?

    – Daniel
    Jan 18 at 23:35






  • 1





    You need to remove <> from friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);

    – Remy Lebeau
    Jan 18 at 23:36













  • Probably don't need to forward declare either the class or friend func

    – Phil M
    Jan 18 at 23:42











  • @Daniel Here: daniweb.com/programming/software-development/threads/65196/… , seemed to make sense to me :(

    – Stef
    Jan 19 at 14:28








3




3





friend std::ostream &operator<< **<>**(std::ostream &os, messageTemplate<A> &aTemplate); Where did you read that you should use the "<>" part?

– Daniel
Jan 18 at 23:35





friend std::ostream &operator<< **<>**(std::ostream &os, messageTemplate<A> &aTemplate); Where did you read that you should use the "<>" part?

– Daniel
Jan 18 at 23:35




1




1





You need to remove <> from friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);

– Remy Lebeau
Jan 18 at 23:36







You need to remove <> from friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);

– Remy Lebeau
Jan 18 at 23:36















Probably don't need to forward declare either the class or friend func

– Phil M
Jan 18 at 23:42





Probably don't need to forward declare either the class or friend func

– Phil M
Jan 18 at 23:42













@Daniel Here: daniweb.com/programming/software-development/threads/65196/… , seemed to make sense to me :(

– Stef
Jan 19 at 14:28





@Daniel Here: daniweb.com/programming/software-development/threads/65196/… , seemed to make sense to me :(

– Stef
Jan 19 at 14:28












2 Answers
2






active

oldest

votes


















1














There are two problems I see:



1) the overloaded function declaration for operator<< contains the characters <> which causes a compile failure. This can be fixed by removing <>



2) the overloaded function definition for operator<< ( and the class ctor ) exists in a source file which causes a linker failure. This can be fixed by moving these definitions from the source file to the header file.



Try using the following header and source files, this works for me...



template.h



#pragma once

#include <iostream>
#include <string>


//class must be forward declared because it contains a friend function template
template<class T> class messageTemplate;

//friend function also must be forwards declared
template<class A> std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

template <class T>
class messageTemplate {
public:
messageTemplate(const std::string &topic, T data);

template <class A>
friend std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

private:
std::string topic;
T data;
};

template<class T>
messageTemplate<T>::messageTemplate(const std::string &topic, T data):topic(topic), data(data) {};

template <class T>
std::ostream &operator<< (std::ostream &os, messageTemplate<T> &aTemplate) {
os << "topic: " << aTemplate.topic << " data: " << aTemplate.data;
return os;
};


main.cpp



#include "template.h"
#include <iostream>

using namespace std;

int main()
{
messageTemplate< int > test{ "test", 69 };

cout << test << endl;

return 0;
}


Console output:



topic: test data: 69

Process finished with exit code 0





share|improve this answer































    0














    Ostensibly, the problem is you're trying to overload not the operator "<<", but the operator "<< <>"



    From the .h file, replace



     friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);


    with



      friend std::ostream &operator<< (std::ostream &os, messageTemplate<A> &aTemplate);





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54262723%2fsimple-template-class-with-overloaded-operator-fails-invalid-use-of-templat%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      There are two problems I see:



      1) the overloaded function declaration for operator<< contains the characters <> which causes a compile failure. This can be fixed by removing <>



      2) the overloaded function definition for operator<< ( and the class ctor ) exists in a source file which causes a linker failure. This can be fixed by moving these definitions from the source file to the header file.



      Try using the following header and source files, this works for me...



      template.h



      #pragma once

      #include <iostream>
      #include <string>


      //class must be forward declared because it contains a friend function template
      template<class T> class messageTemplate;

      //friend function also must be forwards declared
      template<class A> std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

      template <class T>
      class messageTemplate {
      public:
      messageTemplate(const std::string &topic, T data);

      template <class A>
      friend std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

      private:
      std::string topic;
      T data;
      };

      template<class T>
      messageTemplate<T>::messageTemplate(const std::string &topic, T data):topic(topic), data(data) {};

      template <class T>
      std::ostream &operator<< (std::ostream &os, messageTemplate<T> &aTemplate) {
      os << "topic: " << aTemplate.topic << " data: " << aTemplate.data;
      return os;
      };


      main.cpp



      #include "template.h"
      #include <iostream>

      using namespace std;

      int main()
      {
      messageTemplate< int > test{ "test", 69 };

      cout << test << endl;

      return 0;
      }


      Console output:



      topic: test data: 69

      Process finished with exit code 0





      share|improve this answer




























        1














        There are two problems I see:



        1) the overloaded function declaration for operator<< contains the characters <> which causes a compile failure. This can be fixed by removing <>



        2) the overloaded function definition for operator<< ( and the class ctor ) exists in a source file which causes a linker failure. This can be fixed by moving these definitions from the source file to the header file.



        Try using the following header and source files, this works for me...



        template.h



        #pragma once

        #include <iostream>
        #include <string>


        //class must be forward declared because it contains a friend function template
        template<class T> class messageTemplate;

        //friend function also must be forwards declared
        template<class A> std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

        template <class T>
        class messageTemplate {
        public:
        messageTemplate(const std::string &topic, T data);

        template <class A>
        friend std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

        private:
        std::string topic;
        T data;
        };

        template<class T>
        messageTemplate<T>::messageTemplate(const std::string &topic, T data):topic(topic), data(data) {};

        template <class T>
        std::ostream &operator<< (std::ostream &os, messageTemplate<T> &aTemplate) {
        os << "topic: " << aTemplate.topic << " data: " << aTemplate.data;
        return os;
        };


        main.cpp



        #include "template.h"
        #include <iostream>

        using namespace std;

        int main()
        {
        messageTemplate< int > test{ "test", 69 };

        cout << test << endl;

        return 0;
        }


        Console output:



        topic: test data: 69

        Process finished with exit code 0





        share|improve this answer


























          1












          1








          1







          There are two problems I see:



          1) the overloaded function declaration for operator<< contains the characters <> which causes a compile failure. This can be fixed by removing <>



          2) the overloaded function definition for operator<< ( and the class ctor ) exists in a source file which causes a linker failure. This can be fixed by moving these definitions from the source file to the header file.



          Try using the following header and source files, this works for me...



          template.h



          #pragma once

          #include <iostream>
          #include <string>


          //class must be forward declared because it contains a friend function template
          template<class T> class messageTemplate;

          //friend function also must be forwards declared
          template<class A> std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

          template <class T>
          class messageTemplate {
          public:
          messageTemplate(const std::string &topic, T data);

          template <class A>
          friend std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

          private:
          std::string topic;
          T data;
          };

          template<class T>
          messageTemplate<T>::messageTemplate(const std::string &topic, T data):topic(topic), data(data) {};

          template <class T>
          std::ostream &operator<< (std::ostream &os, messageTemplate<T> &aTemplate) {
          os << "topic: " << aTemplate.topic << " data: " << aTemplate.data;
          return os;
          };


          main.cpp



          #include "template.h"
          #include <iostream>

          using namespace std;

          int main()
          {
          messageTemplate< int > test{ "test", 69 };

          cout << test << endl;

          return 0;
          }


          Console output:



          topic: test data: 69

          Process finished with exit code 0





          share|improve this answer













          There are two problems I see:



          1) the overloaded function declaration for operator<< contains the characters <> which causes a compile failure. This can be fixed by removing <>



          2) the overloaded function definition for operator<< ( and the class ctor ) exists in a source file which causes a linker failure. This can be fixed by moving these definitions from the source file to the header file.



          Try using the following header and source files, this works for me...



          template.h



          #pragma once

          #include <iostream>
          #include <string>


          //class must be forward declared because it contains a friend function template
          template<class T> class messageTemplate;

          //friend function also must be forwards declared
          template<class A> std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

          template <class T>
          class messageTemplate {
          public:
          messageTemplate(const std::string &topic, T data);

          template <class A>
          friend std::ostream &operator<<(std::ostream &os, messageTemplate<A> &aTemplate);

          private:
          std::string topic;
          T data;
          };

          template<class T>
          messageTemplate<T>::messageTemplate(const std::string &topic, T data):topic(topic), data(data) {};

          template <class T>
          std::ostream &operator<< (std::ostream &os, messageTemplate<T> &aTemplate) {
          os << "topic: " << aTemplate.topic << " data: " << aTemplate.data;
          return os;
          };


          main.cpp



          #include "template.h"
          #include <iostream>

          using namespace std;

          int main()
          {
          messageTemplate< int > test{ "test", 69 };

          cout << test << endl;

          return 0;
          }


          Console output:



          topic: test data: 69

          Process finished with exit code 0






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 19 at 1:38









          claytonjwongclaytonjwong

          13218




          13218

























              0














              Ostensibly, the problem is you're trying to overload not the operator "<<", but the operator "<< <>"



              From the .h file, replace



               friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);


              with



                friend std::ostream &operator<< (std::ostream &os, messageTemplate<A> &aTemplate);





              share|improve this answer




























                0














                Ostensibly, the problem is you're trying to overload not the operator "<<", but the operator "<< <>"



                From the .h file, replace



                 friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);


                with



                  friend std::ostream &operator<< (std::ostream &os, messageTemplate<A> &aTemplate);





                share|improve this answer


























                  0












                  0








                  0







                  Ostensibly, the problem is you're trying to overload not the operator "<<", but the operator "<< <>"



                  From the .h file, replace



                   friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);


                  with



                    friend std::ostream &operator<< (std::ostream &os, messageTemplate<A> &aTemplate);





                  share|improve this answer













                  Ostensibly, the problem is you're trying to overload not the operator "<<", but the operator "<< <>"



                  From the .h file, replace



                   friend std::ostream &operator<< <>(std::ostream &os, messageTemplate<A> &aTemplate);


                  with



                    friend std::ostream &operator<< (std::ostream &os, messageTemplate<A> &aTemplate);






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 18 at 23:39









                  DanielDaniel

                  387114




                  387114






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54262723%2fsimple-template-class-with-overloaded-operator-fails-invalid-use-of-templat%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Liquibase includeAll doesn't find base path

                      How to use setInterval in EJS file?

                      Petrus Granier-Deferre