Template deduction complaints ambiguous candidates












6














I intend to implement the multiplication operator of my "Sparse Vector" and "Vector" classes. The following simplified code demo shows my problem



The Vector class in Vector.hpp



#pragma once

template <typename T>
class Vector
{
public:
Vector() {}

template <typename Scalar>
friend Vector operator*(const Scalar &a, const Vector &rhs) // #1
{
return Vector();
}
};


The Sparse Vector class in SpVec.hpp



#pragma once
#include "Vector.hpp"

template <typename T>
class SpVec
{
public:
SpVec() {}

template <typename U>
inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
{
return 0.0;
}
};


The test code in main.cpp:



#include "Vector.hpp"
#include "SpVec.hpp"


#include <iostream>

int main()
{
Vector<double> v;

SpVec<double> spv;

std::cout << spv * v;
return 0;
}


I build the test program with



g++ main.cpp -o test


which gives the ambiguous template deduction error



main.cpp: In function ‘int main()’:
main.cpp:13:26: error: ambiguous overload for ‘operator*’ (operand types are ‘SpVec<double>’ and ‘Vector<double>’)
std::cout << spv * v;
~~~~^~~
In file included from main.cpp:2:0:
SpVec.hpp:12:26: note: candidate: double operator*(const SpVec<T>&, const Vector<U>&) [with U = double; T = double]
inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
^~~~~~~~
In file included from main.cpp:1:0:
Vector.hpp:10:19: note: candidate: Vector<T> operator*(const Scalar&, const Vector<T>&) [with Scalar = SpVec<double>; T = double]
friend Vector operator*(const Scalar &a, const Vector &rhs) // #1


I expect the #2 method definition is more close to my calling.



Please help me understand how the ambiguous error comes out and how to resolve the issue.










share|improve this question



























    6














    I intend to implement the multiplication operator of my "Sparse Vector" and "Vector" classes. The following simplified code demo shows my problem



    The Vector class in Vector.hpp



    #pragma once

    template <typename T>
    class Vector
    {
    public:
    Vector() {}

    template <typename Scalar>
    friend Vector operator*(const Scalar &a, const Vector &rhs) // #1
    {
    return Vector();
    }
    };


    The Sparse Vector class in SpVec.hpp



    #pragma once
    #include "Vector.hpp"

    template <typename T>
    class SpVec
    {
    public:
    SpVec() {}

    template <typename U>
    inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
    {
    return 0.0;
    }
    };


    The test code in main.cpp:



    #include "Vector.hpp"
    #include "SpVec.hpp"


    #include <iostream>

    int main()
    {
    Vector<double> v;

    SpVec<double> spv;

    std::cout << spv * v;
    return 0;
    }


    I build the test program with



    g++ main.cpp -o test


    which gives the ambiguous template deduction error



    main.cpp: In function ‘int main()’:
    main.cpp:13:26: error: ambiguous overload for ‘operator*’ (operand types are ‘SpVec<double>’ and ‘Vector<double>’)
    std::cout << spv * v;
    ~~~~^~~
    In file included from main.cpp:2:0:
    SpVec.hpp:12:26: note: candidate: double operator*(const SpVec<T>&, const Vector<U>&) [with U = double; T = double]
    inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
    ^~~~~~~~
    In file included from main.cpp:1:0:
    Vector.hpp:10:19: note: candidate: Vector<T> operator*(const Scalar&, const Vector<T>&) [with Scalar = SpVec<double>; T = double]
    friend Vector operator*(const Scalar &a, const Vector &rhs) // #1


    I expect the #2 method definition is more close to my calling.



    Please help me understand how the ambiguous error comes out and how to resolve the issue.










    share|improve this question

























      6












      6








      6


      1





      I intend to implement the multiplication operator of my "Sparse Vector" and "Vector" classes. The following simplified code demo shows my problem



      The Vector class in Vector.hpp



      #pragma once

      template <typename T>
      class Vector
      {
      public:
      Vector() {}

      template <typename Scalar>
      friend Vector operator*(const Scalar &a, const Vector &rhs) // #1
      {
      return Vector();
      }
      };


      The Sparse Vector class in SpVec.hpp



      #pragma once
      #include "Vector.hpp"

      template <typename T>
      class SpVec
      {
      public:
      SpVec() {}

      template <typename U>
      inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
      {
      return 0.0;
      }
      };


      The test code in main.cpp:



      #include "Vector.hpp"
      #include "SpVec.hpp"


      #include <iostream>

      int main()
      {
      Vector<double> v;

      SpVec<double> spv;

      std::cout << spv * v;
      return 0;
      }


      I build the test program with



      g++ main.cpp -o test


      which gives the ambiguous template deduction error



      main.cpp: In function ‘int main()’:
      main.cpp:13:26: error: ambiguous overload for ‘operator*’ (operand types are ‘SpVec<double>’ and ‘Vector<double>’)
      std::cout << spv * v;
      ~~~~^~~
      In file included from main.cpp:2:0:
      SpVec.hpp:12:26: note: candidate: double operator*(const SpVec<T>&, const Vector<U>&) [with U = double; T = double]
      inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
      ^~~~~~~~
      In file included from main.cpp:1:0:
      Vector.hpp:10:19: note: candidate: Vector<T> operator*(const Scalar&, const Vector<T>&) [with Scalar = SpVec<double>; T = double]
      friend Vector operator*(const Scalar &a, const Vector &rhs) // #1


      I expect the #2 method definition is more close to my calling.



      Please help me understand how the ambiguous error comes out and how to resolve the issue.










      share|improve this question













      I intend to implement the multiplication operator of my "Sparse Vector" and "Vector" classes. The following simplified code demo shows my problem



      The Vector class in Vector.hpp



      #pragma once

      template <typename T>
      class Vector
      {
      public:
      Vector() {}

      template <typename Scalar>
      friend Vector operator*(const Scalar &a, const Vector &rhs) // #1
      {
      return Vector();
      }
      };


      The Sparse Vector class in SpVec.hpp



      #pragma once
      #include "Vector.hpp"

      template <typename T>
      class SpVec
      {
      public:
      SpVec() {}

      template <typename U>
      inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
      {
      return 0.0;
      }
      };


      The test code in main.cpp:



      #include "Vector.hpp"
      #include "SpVec.hpp"


      #include <iostream>

      int main()
      {
      Vector<double> v;

      SpVec<double> spv;

      std::cout << spv * v;
      return 0;
      }


      I build the test program with



      g++ main.cpp -o test


      which gives the ambiguous template deduction error



      main.cpp: In function ‘int main()’:
      main.cpp:13:26: error: ambiguous overload for ‘operator*’ (operand types are ‘SpVec<double>’ and ‘Vector<double>’)
      std::cout << spv * v;
      ~~~~^~~
      In file included from main.cpp:2:0:
      SpVec.hpp:12:26: note: candidate: double operator*(const SpVec<T>&, const Vector<U>&) [with U = double; T = double]
      inline friend double operator*(const SpVec &spv, const Vector<U> &v) // #2
      ^~~~~~~~
      In file included from main.cpp:1:0:
      Vector.hpp:10:19: note: candidate: Vector<T> operator*(const Scalar&, const Vector<T>&) [with Scalar = SpVec<double>; T = double]
      friend Vector operator*(const Scalar &a, const Vector &rhs) // #1


      I expect the #2 method definition is more close to my calling.



      Please help me understand how the ambiguous error comes out and how to resolve the issue.







      c++ templates metaprogramming ambiguous






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 13 '18 at 5:58









      RubinRubin

      1037




      1037
























          2 Answers
          2






          active

          oldest

          votes


















          3














          I come up with another idea that the prior type information Scalar can be used with the SFAINE feature enabled by the c++11 standard library struct std::enable_if.



          The codes:



          Vector.hpp



          #pragma once

          #include <iostream>
          #include <type_traits>

          template <typename T>
          class Vector
          {
          public:
          Vector() {}

          template <typename Scalar>
          typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
          operator*(const Scalar &rhs) const// #1
          {
          std::cout << "Vector * Scalar called." << std::endl;
          return Vector();
          }

          template <typename Scalar>
          inline friend typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
          operator*(const Scalar &lhs, const Vector &rhs)
          {
          std::cout << "Scalar * Vector called." << std::endl;
          return Vector();
          }
          };


          SpVec.hpp



          #pragma once
          #include "Vector.hpp"

          #include <iostream>

          template <typename T>
          class SpVec
          {
          public:
          SpVec() {}

          template <typename U>
          inline double operator*(const Vector<U> &rhs) const // #2 as member function
          {
          std::cout << "SpVec * Vector called" << std::endl;
          return 0.0;
          }

          template <typename U>
          inline friend double operator*(const Vector<U> &lhs, const SpVec &rhs)
          {
          std::cout << "Vector * SpVec called" << std::endl;
          return 0.0;
          }
          };


          main.cpp



          #include "SpVec.hpp"
          #include "Vector.hpp"

          #include <iostream>

          int main()
          {
          Vector<double> v;
          SpVec<double> spv;

          double a = spv * v;
          a = v * spv;

          Vector<double> vt;
          vt = v * 2.0;
          vt = 2.0 * v;

          return 0;
          }


          Build the program with c++11



          g++ -std=c++11 main.cpp -o test


          The result:



          SpVec * Vector called.
          Vector * SpVec called.
          Vector * Scalar called.
          Scalar * Vector called.





          share|improve this answer























          • That's also a nice one !
            – Christophe
            Nov 13 '18 at 8:34



















          0














          The argument to operator* are SpVec<double> and Vector<double>. It could be resolved to



          operator*(const Scalar &a, const Vector &rhs) with scalar as SpVec<double> and rhs as Vector<double>.



          It could also resolve to



          operator*(const SpVec &spv, const Vector<U> &v) with spv as SpVec<double> and U as double.



          One way of resolving this is to turn Vector::operator* to non-friend function.



          Vector operator*(const Scalar &a)     // #1
          {
          //The other argument here will be accessed using this pointer.
          return Vector();
          }


          and you can call it as



          int main() 
          {
          Vector<double> v;
          SpVec<double> spv;
          std::cout << spv * v; // will call #2
          v * spv; //will call #1
          return 0;
          }





          share|improve this answer





















          • You beat me to it!
            – Francis Cugler
            Nov 13 '18 at 6:47










          • Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
            – Rubin
            Nov 13 '18 at 6:57










          • Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
            – Christophe
            Nov 13 '18 at 7:06












          • @Rubin I think the term you are looking for is commutate and not precedence. The commutative property says that a*b is equal to b*a. Precedence is used to decide in which order several operators are executed: a + b * c where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…
            – Philipp
            Nov 13 '18 at 7:41










          • @Philipp Thanks for the correction. The commutative property is indeed what I need.
            – Rubin
            Nov 13 '18 at 7:49











          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%2f53274692%2ftemplate-deduction-complaints-ambiguous-candidates%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









          3














          I come up with another idea that the prior type information Scalar can be used with the SFAINE feature enabled by the c++11 standard library struct std::enable_if.



          The codes:



          Vector.hpp



          #pragma once

          #include <iostream>
          #include <type_traits>

          template <typename T>
          class Vector
          {
          public:
          Vector() {}

          template <typename Scalar>
          typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
          operator*(const Scalar &rhs) const// #1
          {
          std::cout << "Vector * Scalar called." << std::endl;
          return Vector();
          }

          template <typename Scalar>
          inline friend typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
          operator*(const Scalar &lhs, const Vector &rhs)
          {
          std::cout << "Scalar * Vector called." << std::endl;
          return Vector();
          }
          };


          SpVec.hpp



          #pragma once
          #include "Vector.hpp"

          #include <iostream>

          template <typename T>
          class SpVec
          {
          public:
          SpVec() {}

          template <typename U>
          inline double operator*(const Vector<U> &rhs) const // #2 as member function
          {
          std::cout << "SpVec * Vector called" << std::endl;
          return 0.0;
          }

          template <typename U>
          inline friend double operator*(const Vector<U> &lhs, const SpVec &rhs)
          {
          std::cout << "Vector * SpVec called" << std::endl;
          return 0.0;
          }
          };


          main.cpp



          #include "SpVec.hpp"
          #include "Vector.hpp"

          #include <iostream>

          int main()
          {
          Vector<double> v;
          SpVec<double> spv;

          double a = spv * v;
          a = v * spv;

          Vector<double> vt;
          vt = v * 2.0;
          vt = 2.0 * v;

          return 0;
          }


          Build the program with c++11



          g++ -std=c++11 main.cpp -o test


          The result:



          SpVec * Vector called.
          Vector * SpVec called.
          Vector * Scalar called.
          Scalar * Vector called.





          share|improve this answer























          • That's also a nice one !
            – Christophe
            Nov 13 '18 at 8:34
















          3














          I come up with another idea that the prior type information Scalar can be used with the SFAINE feature enabled by the c++11 standard library struct std::enable_if.



          The codes:



          Vector.hpp



          #pragma once

          #include <iostream>
          #include <type_traits>

          template <typename T>
          class Vector
          {
          public:
          Vector() {}

          template <typename Scalar>
          typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
          operator*(const Scalar &rhs) const// #1
          {
          std::cout << "Vector * Scalar called." << std::endl;
          return Vector();
          }

          template <typename Scalar>
          inline friend typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
          operator*(const Scalar &lhs, const Vector &rhs)
          {
          std::cout << "Scalar * Vector called." << std::endl;
          return Vector();
          }
          };


          SpVec.hpp



          #pragma once
          #include "Vector.hpp"

          #include <iostream>

          template <typename T>
          class SpVec
          {
          public:
          SpVec() {}

          template <typename U>
          inline double operator*(const Vector<U> &rhs) const // #2 as member function
          {
          std::cout << "SpVec * Vector called" << std::endl;
          return 0.0;
          }

          template <typename U>
          inline friend double operator*(const Vector<U> &lhs, const SpVec &rhs)
          {
          std::cout << "Vector * SpVec called" << std::endl;
          return 0.0;
          }
          };


          main.cpp



          #include "SpVec.hpp"
          #include "Vector.hpp"

          #include <iostream>

          int main()
          {
          Vector<double> v;
          SpVec<double> spv;

          double a = spv * v;
          a = v * spv;

          Vector<double> vt;
          vt = v * 2.0;
          vt = 2.0 * v;

          return 0;
          }


          Build the program with c++11



          g++ -std=c++11 main.cpp -o test


          The result:



          SpVec * Vector called.
          Vector * SpVec called.
          Vector * Scalar called.
          Scalar * Vector called.





          share|improve this answer























          • That's also a nice one !
            – Christophe
            Nov 13 '18 at 8:34














          3












          3








          3






          I come up with another idea that the prior type information Scalar can be used with the SFAINE feature enabled by the c++11 standard library struct std::enable_if.



          The codes:



          Vector.hpp



          #pragma once

          #include <iostream>
          #include <type_traits>

          template <typename T>
          class Vector
          {
          public:
          Vector() {}

          template <typename Scalar>
          typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
          operator*(const Scalar &rhs) const// #1
          {
          std::cout << "Vector * Scalar called." << std::endl;
          return Vector();
          }

          template <typename Scalar>
          inline friend typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
          operator*(const Scalar &lhs, const Vector &rhs)
          {
          std::cout << "Scalar * Vector called." << std::endl;
          return Vector();
          }
          };


          SpVec.hpp



          #pragma once
          #include "Vector.hpp"

          #include <iostream>

          template <typename T>
          class SpVec
          {
          public:
          SpVec() {}

          template <typename U>
          inline double operator*(const Vector<U> &rhs) const // #2 as member function
          {
          std::cout << "SpVec * Vector called" << std::endl;
          return 0.0;
          }

          template <typename U>
          inline friend double operator*(const Vector<U> &lhs, const SpVec &rhs)
          {
          std::cout << "Vector * SpVec called" << std::endl;
          return 0.0;
          }
          };


          main.cpp



          #include "SpVec.hpp"
          #include "Vector.hpp"

          #include <iostream>

          int main()
          {
          Vector<double> v;
          SpVec<double> spv;

          double a = spv * v;
          a = v * spv;

          Vector<double> vt;
          vt = v * 2.0;
          vt = 2.0 * v;

          return 0;
          }


          Build the program with c++11



          g++ -std=c++11 main.cpp -o test


          The result:



          SpVec * Vector called.
          Vector * SpVec called.
          Vector * Scalar called.
          Scalar * Vector called.





          share|improve this answer














          I come up with another idea that the prior type information Scalar can be used with the SFAINE feature enabled by the c++11 standard library struct std::enable_if.



          The codes:



          Vector.hpp



          #pragma once

          #include <iostream>
          #include <type_traits>

          template <typename T>
          class Vector
          {
          public:
          Vector() {}

          template <typename Scalar>
          typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
          operator*(const Scalar &rhs) const// #1
          {
          std::cout << "Vector * Scalar called." << std::endl;
          return Vector();
          }

          template <typename Scalar>
          inline friend typename std::enable_if<std::is_arithmetic<Scalar>::value, Vector<T>>::type
          operator*(const Scalar &lhs, const Vector &rhs)
          {
          std::cout << "Scalar * Vector called." << std::endl;
          return Vector();
          }
          };


          SpVec.hpp



          #pragma once
          #include "Vector.hpp"

          #include <iostream>

          template <typename T>
          class SpVec
          {
          public:
          SpVec() {}

          template <typename U>
          inline double operator*(const Vector<U> &rhs) const // #2 as member function
          {
          std::cout << "SpVec * Vector called" << std::endl;
          return 0.0;
          }

          template <typename U>
          inline friend double operator*(const Vector<U> &lhs, const SpVec &rhs)
          {
          std::cout << "Vector * SpVec called" << std::endl;
          return 0.0;
          }
          };


          main.cpp



          #include "SpVec.hpp"
          #include "Vector.hpp"

          #include <iostream>

          int main()
          {
          Vector<double> v;
          SpVec<double> spv;

          double a = spv * v;
          a = v * spv;

          Vector<double> vt;
          vt = v * 2.0;
          vt = 2.0 * v;

          return 0;
          }


          Build the program with c++11



          g++ -std=c++11 main.cpp -o test


          The result:



          SpVec * Vector called.
          Vector * SpVec called.
          Vector * Scalar called.
          Scalar * Vector called.






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 13 '18 at 11:14









          Oliv

          8,5191956




          8,5191956










          answered Nov 13 '18 at 8:30









          RubinRubin

          1037




          1037












          • That's also a nice one !
            – Christophe
            Nov 13 '18 at 8:34


















          • That's also a nice one !
            – Christophe
            Nov 13 '18 at 8:34
















          That's also a nice one !
          – Christophe
          Nov 13 '18 at 8:34




          That's also a nice one !
          – Christophe
          Nov 13 '18 at 8:34













          0














          The argument to operator* are SpVec<double> and Vector<double>. It could be resolved to



          operator*(const Scalar &a, const Vector &rhs) with scalar as SpVec<double> and rhs as Vector<double>.



          It could also resolve to



          operator*(const SpVec &spv, const Vector<U> &v) with spv as SpVec<double> and U as double.



          One way of resolving this is to turn Vector::operator* to non-friend function.



          Vector operator*(const Scalar &a)     // #1
          {
          //The other argument here will be accessed using this pointer.
          return Vector();
          }


          and you can call it as



          int main() 
          {
          Vector<double> v;
          SpVec<double> spv;
          std::cout << spv * v; // will call #2
          v * spv; //will call #1
          return 0;
          }





          share|improve this answer





















          • You beat me to it!
            – Francis Cugler
            Nov 13 '18 at 6:47










          • Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
            – Rubin
            Nov 13 '18 at 6:57










          • Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
            – Christophe
            Nov 13 '18 at 7:06












          • @Rubin I think the term you are looking for is commutate and not precedence. The commutative property says that a*b is equal to b*a. Precedence is used to decide in which order several operators are executed: a + b * c where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…
            – Philipp
            Nov 13 '18 at 7:41










          • @Philipp Thanks for the correction. The commutative property is indeed what I need.
            – Rubin
            Nov 13 '18 at 7:49
















          0














          The argument to operator* are SpVec<double> and Vector<double>. It could be resolved to



          operator*(const Scalar &a, const Vector &rhs) with scalar as SpVec<double> and rhs as Vector<double>.



          It could also resolve to



          operator*(const SpVec &spv, const Vector<U> &v) with spv as SpVec<double> and U as double.



          One way of resolving this is to turn Vector::operator* to non-friend function.



          Vector operator*(const Scalar &a)     // #1
          {
          //The other argument here will be accessed using this pointer.
          return Vector();
          }


          and you can call it as



          int main() 
          {
          Vector<double> v;
          SpVec<double> spv;
          std::cout << spv * v; // will call #2
          v * spv; //will call #1
          return 0;
          }





          share|improve this answer





















          • You beat me to it!
            – Francis Cugler
            Nov 13 '18 at 6:47










          • Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
            – Rubin
            Nov 13 '18 at 6:57










          • Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
            – Christophe
            Nov 13 '18 at 7:06












          • @Rubin I think the term you are looking for is commutate and not precedence. The commutative property says that a*b is equal to b*a. Precedence is used to decide in which order several operators are executed: a + b * c where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…
            – Philipp
            Nov 13 '18 at 7:41










          • @Philipp Thanks for the correction. The commutative property is indeed what I need.
            – Rubin
            Nov 13 '18 at 7:49














          0












          0








          0






          The argument to operator* are SpVec<double> and Vector<double>. It could be resolved to



          operator*(const Scalar &a, const Vector &rhs) with scalar as SpVec<double> and rhs as Vector<double>.



          It could also resolve to



          operator*(const SpVec &spv, const Vector<U> &v) with spv as SpVec<double> and U as double.



          One way of resolving this is to turn Vector::operator* to non-friend function.



          Vector operator*(const Scalar &a)     // #1
          {
          //The other argument here will be accessed using this pointer.
          return Vector();
          }


          and you can call it as



          int main() 
          {
          Vector<double> v;
          SpVec<double> spv;
          std::cout << spv * v; // will call #2
          v * spv; //will call #1
          return 0;
          }





          share|improve this answer












          The argument to operator* are SpVec<double> and Vector<double>. It could be resolved to



          operator*(const Scalar &a, const Vector &rhs) with scalar as SpVec<double> and rhs as Vector<double>.



          It could also resolve to



          operator*(const SpVec &spv, const Vector<U> &v) with spv as SpVec<double> and U as double.



          One way of resolving this is to turn Vector::operator* to non-friend function.



          Vector operator*(const Scalar &a)     // #1
          {
          //The other argument here will be accessed using this pointer.
          return Vector();
          }


          and you can call it as



          int main() 
          {
          Vector<double> v;
          SpVec<double> spv;
          std::cout << spv * v; // will call #2
          v * spv; //will call #1
          return 0;
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 13 '18 at 6:40









          Gaurav SehgalGaurav Sehgal

          5,68111026




          5,68111026












          • You beat me to it!
            – Francis Cugler
            Nov 13 '18 at 6:47










          • Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
            – Rubin
            Nov 13 '18 at 6:57










          • Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
            – Christophe
            Nov 13 '18 at 7:06












          • @Rubin I think the term you are looking for is commutate and not precedence. The commutative property says that a*b is equal to b*a. Precedence is used to decide in which order several operators are executed: a + b * c where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…
            – Philipp
            Nov 13 '18 at 7:41










          • @Philipp Thanks for the correction. The commutative property is indeed what I need.
            – Rubin
            Nov 13 '18 at 7:49


















          • You beat me to it!
            – Francis Cugler
            Nov 13 '18 at 6:47










          • Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
            – Rubin
            Nov 13 '18 at 6:57










          • Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
            – Christophe
            Nov 13 '18 at 7:06












          • @Rubin I think the term you are looking for is commutate and not precedence. The commutative property says that a*b is equal to b*a. Precedence is used to decide in which order several operators are executed: a + b * c where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…
            – Philipp
            Nov 13 '18 at 7:41










          • @Philipp Thanks for the correction. The commutative property is indeed what I need.
            – Rubin
            Nov 13 '18 at 7:49
















          You beat me to it!
          – Francis Cugler
          Nov 13 '18 at 6:47




          You beat me to it!
          – Francis Cugler
          Nov 13 '18 at 6:47












          Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
          – Rubin
          Nov 13 '18 at 6:57




          Thanks. This suggestion does work. For the deeper discussion, is it possible to make the two cases both work as no operands precedence need to be cared about for the user?
          – Rubin
          Nov 13 '18 at 6:57












          Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
          – Christophe
          Nov 13 '18 at 7:06






          Nice answer. However, this works only because you play with the order of the parameters (with an operator that is assumed to be commutative).
          – Christophe
          Nov 13 '18 at 7:06














          @Rubin I think the term you are looking for is commutate and not precedence. The commutative property says that a*b is equal to b*a. Precedence is used to decide in which order several operators are executed: a + b * c where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…
          – Philipp
          Nov 13 '18 at 7:41




          @Rubin I think the term you are looking for is commutate and not precedence. The commutative property says that a*b is equal to b*a. Precedence is used to decide in which order several operators are executed: a + b * c where multiplication has a higher precedence and will be calculated before the addition. Also here a link to a question about commutative property in the non-templated case: stackoverflow.com/questions/3764604/…
          – Philipp
          Nov 13 '18 at 7:41












          @Philipp Thanks for the correction. The commutative property is indeed what I need.
          – Rubin
          Nov 13 '18 at 7:49




          @Philipp Thanks for the correction. The commutative property is indeed what I need.
          – Rubin
          Nov 13 '18 at 7:49


















          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%2f53274692%2ftemplate-deduction-complaints-ambiguous-candidates%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







          這個網誌中的熱門文章

          Hercules Kyvelos

          Tangent Lines Diagram Along Smooth Curve

          Yusuf al-Mu'taman ibn Hud