Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Friend Operators of Template Classes

Friend Operators of Template Classes

Scheduled Pinned Locked Moved C / C++ / MFC
helpcsharpc++javahtml
6 Posts 3 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Skippums
    wrote on last edited by
    #1

    First, the problem: I have a template class (Foo) that will have a friend operator + that takes type T as the first parameter, and type Foo<T> as the second. The forward declaration is:

    template<class T> struct Foo;
    template<class T> Foo<T> operator +(T const a1, Foo<T> const &a2);

    I am using Visual Studio 2010 Pro. Doing a search resulted in the following two links that I thought would be helpful: http://www.parashift.com/c++-faq-lite/template-friends.html[^] http://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/index.jsp?topic=/com.ibm.vacpp7l.doc/language/ref/clrc16friends_and_templates.htm[^] These recommendations lead me to try the following after the above forward declaration:

    template<class T = double>
    struct Foo {
    private:
    T m_Data;
    // The following all result in the specified error when attempting to use this friend
    // LNK2019: unresolved external symbol "struct Foo<double> __cdecl operator+(
    // double, struct Foo<double> const &)" ...
    friend Foo<T> operator +(T const a1, Foo<T> const &a2);
    // C2143: syntax error : missing ';' before '<'
    // C2460: '+' : uses 'Foo<T>', which is being defined
    // C2433: '+' : 'friend' not permitted on data declarations
    // C2365: 'operator +' : redefinition; previous definition was 'function'
    // C2238: unexpected token(s) preceding ';'
    friend Foo<T> operator + <>(T const a1, Foo<T> const &a2);
    // Same errors as above (C2143, C2460, C2433, C2365, C2238)
    friend Foo<T> operator + <T>(T const a1, Foo<T> const &a2);
    // C3637: 'operator +' : a friend function definition cannot be a specialization of a function template
    // C3412: 'operator +' : cannot specialize template in current scope
    template<>
    friend Foo<T> operator +(T const a1, Foo<T> const &a2);

    public:
    Foo operato

    F S 2 Replies Last reply
    0
    • S Skippums

      First, the problem: I have a template class (Foo) that will have a friend operator + that takes type T as the first parameter, and type Foo<T> as the second. The forward declaration is:

      template<class T> struct Foo;
      template<class T> Foo<T> operator +(T const a1, Foo<T> const &a2);

      I am using Visual Studio 2010 Pro. Doing a search resulted in the following two links that I thought would be helpful: http://www.parashift.com/c++-faq-lite/template-friends.html[^] http://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/index.jsp?topic=/com.ibm.vacpp7l.doc/language/ref/clrc16friends_and_templates.htm[^] These recommendations lead me to try the following after the above forward declaration:

      template<class T = double>
      struct Foo {
      private:
      T m_Data;
      // The following all result in the specified error when attempting to use this friend
      // LNK2019: unresolved external symbol "struct Foo<double> __cdecl operator+(
      // double, struct Foo<double> const &)" ...
      friend Foo<T> operator +(T const a1, Foo<T> const &a2);
      // C2143: syntax error : missing ';' before '<'
      // C2460: '+' : uses 'Foo<T>', which is being defined
      // C2433: '+' : 'friend' not permitted on data declarations
      // C2365: 'operator +' : redefinition; previous definition was 'function'
      // C2238: unexpected token(s) preceding ';'
      friend Foo<T> operator + <>(T const a1, Foo<T> const &a2);
      // Same errors as above (C2143, C2460, C2433, C2365, C2238)
      friend Foo<T> operator + <T>(T const a1, Foo<T> const &a2);
      // C3637: 'operator +' : a friend function definition cannot be a specialization of a function template
      // C3412: 'operator +' : cannot specialize template in current scope
      template<>
      friend Foo<T> operator +(T const a1, Foo<T> const &a2);

      public:
      Foo operato

      F Offline
      F Offline
      Freak30
      wrote on last edited by
      #2

      I think you need to explicitely add an inline to the declaration as well as the definition. We had a similar problem with a derived template class and solved it that way.

      The good thing about pessimism is, that you are always either right or pleasently surprised.

      S 1 Reply Last reply
      0
      • S Skippums

        First, the problem: I have a template class (Foo) that will have a friend operator + that takes type T as the first parameter, and type Foo<T> as the second. The forward declaration is:

        template<class T> struct Foo;
        template<class T> Foo<T> operator +(T const a1, Foo<T> const &a2);

        I am using Visual Studio 2010 Pro. Doing a search resulted in the following two links that I thought would be helpful: http://www.parashift.com/c++-faq-lite/template-friends.html[^] http://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/index.jsp?topic=/com.ibm.vacpp7l.doc/language/ref/clrc16friends_and_templates.htm[^] These recommendations lead me to try the following after the above forward declaration:

        template<class T = double>
        struct Foo {
        private:
        T m_Data;
        // The following all result in the specified error when attempting to use this friend
        // LNK2019: unresolved external symbol "struct Foo<double> __cdecl operator+(
        // double, struct Foo<double> const &)" ...
        friend Foo<T> operator +(T const a1, Foo<T> const &a2);
        // C2143: syntax error : missing ';' before '<'
        // C2460: '+' : uses 'Foo<T>', which is being defined
        // C2433: '+' : 'friend' not permitted on data declarations
        // C2365: 'operator +' : redefinition; previous definition was 'function'
        // C2238: unexpected token(s) preceding ';'
        friend Foo<T> operator + <>(T const a1, Foo<T> const &a2);
        // Same errors as above (C2143, C2460, C2433, C2365, C2238)
        friend Foo<T> operator + <T>(T const a1, Foo<T> const &a2);
        // C3637: 'operator +' : a friend function definition cannot be a specialization of a function template
        // C3412: 'operator +' : cannot specialize template in current scope
        template<>
        friend Foo<T> operator +(T const a1, Foo<T> const &a2);

        public:
        Foo operato

        S Offline
        S Offline
        Stefan_Lang
        wrote on last edited by
        #3

        Here's something that worked for me:

        template class iReadContainer
        {
        template friend bool operator== (const iReadContainer<BaseType>& one, const iReadContainer<BaseType>& other);
        };

        P.S.: In previous versions of VS this didnt work either. back then I used to declare a friend helper class in such cases, e. g. :

        template
        class vec3 {
        T val[3];
        public:
        ...
        friend class vec3_operator_helper; // no template argument required
        };
        class vec3_operator_helper {
        public:
        template static
        vec3 add (const vec3& v1, const vec3& v2); // already befriended - just access vec3 members!
        };
        // operator declaration
        template
        vec3 operator+(const vec3& v1, const vec3& v2);
        // operator implementation
        template
        vec3 operator+(const vec3& v1, const vec3& v2) {
        return vec3_operator_helper::add(v1, v2);
        }

        GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

        S 1 Reply Last reply
        0
        • S Stefan_Lang

          Here's something that worked for me:

          template class iReadContainer
          {
          template friend bool operator== (const iReadContainer<BaseType>& one, const iReadContainer<BaseType>& other);
          };

          P.S.: In previous versions of VS this didnt work either. back then I used to declare a friend helper class in such cases, e. g. :

          template
          class vec3 {
          T val[3];
          public:
          ...
          friend class vec3_operator_helper; // no template argument required
          };
          class vec3_operator_helper {
          public:
          template static
          vec3 add (const vec3& v1, const vec3& v2); // already befriended - just access vec3 members!
          };
          // operator declaration
          template
          vec3 operator+(const vec3& v1, const vec3& v2);
          // operator implementation
          template
          vec3 operator+(const vec3& v1, const vec3& v2) {
          return vec3_operator_helper::add(v1, v2);
          }

          GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

          S Offline
          S Offline
          Skippums
          wrote on last edited by
          #4

          Unfortunately, your first recommendation didn't work for me. However, I was also getting intellisense errors when building with the method definition within the declaration. Adding

          template<class>

          prior to the definition prevented those errors from appearing. Note that intellisense errors do not prevent code from successfully compiling. I am sure your second recomendation would work, but it is a bit verbose for what I am attempting to accomplish, so I decided to move the definitions into the header file. Thanks,

          Sounds like somebody's got a case of the Mondays -Jeff

          S 1 Reply Last reply
          0
          • F Freak30

            I think you need to explicitely add an inline to the declaration as well as the definition. We had a similar problem with a derived template class and solved it that way.

            The good thing about pessimism is, that you are always either right or pleasently surprised.

            S Offline
            S Offline
            Skippums
            wrote on last edited by
            #5

            Unfortunately, marking the declarations inline had no noticeable effect. Thanks for the suggestion, though.

            Sounds like somebody's got a case of the Mondays -Jeff

            1 Reply Last reply
            0
            • S Skippums

              Unfortunately, your first recommendation didn't work for me. However, I was also getting intellisense errors when building with the method definition within the declaration. Adding

              template<class>

              prior to the definition prevented those errors from appearing. Note that intellisense errors do not prevent code from successfully compiling. I am sure your second recomendation would work, but it is a bit verbose for what I am attempting to accomplish, so I decided to move the definitions into the header file. Thanks,

              Sounds like somebody's got a case of the Mondays -Jeff

              S Offline
              S Offline
              Stefan_Lang
              wrote on last edited by
              #6

              Hmm, that's odd, I also use VS 2010. I don't use Intellisense though, since I've installed VisualAssist X which works a lot better and is less intrusive. I agree that my second suggestion is rather awkward, but I used it anyway because there were a lot of operators to declare in that particular case! It's probably not worth it if you only have two or three ...

              GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups