template, cast, and operator

Discussion in 'C++' started by thomas.grund@mail.com, Jan 7, 2013.

  1. Guest

    Hello,

    the following does not compile due to problems with the + operator. The same thing works without templates. How can I achive this?

    Thanks a lot,

    Thomas


    template <typename T = double> class CVariable {
    };

    template <typename T = double> class CSymbolic {
    public:
    CSymbolic(CVariable<T>){}
    CSymbolic(){}
    };

    template <typename T> CSymbolic<T> operator+(CSymbolic<T> a1, CSymbolic<T> a2) {
    return CSymbolic();
    }

    int main() {
    CVariable<> x, y;
    CSymbolic<> f1 = x+y; // problem here
    }
     
    , Jan 7, 2013
    #1
    1. Advertising

  2. Zhihao Yuan Guest

    On Monday, January 7, 2013 12:29:58 PM UTC-6, wrote:
    > template <typename T> CSymbolic<T> operator+(CSymbolic<T> a1, CSymbolic<T> a2) {
    > return CSymbolic();
    > }


    Since CVariable<> is not convertible to CSymbolic, this overload is
    not selected. Make it convertible (you may need a forward
    declaration), or have one more overload.

    --
    Zhihao Yuan, ID lichray
    The best way to predict the future is to invent it.
    ___________________________________________________
    4BSD -- http://4bsd.biz/
     
    Zhihao Yuan, Jan 7, 2013
    #2
    1. Advertising

  3. On 1/7/2013 1:29 PM, wrote:
    > the following does not compile due to problems with the + operator. The same thing works without templates. How can I achive this?
    >
    > Thanks a lot,
    >
    > Thomas
    >
    >
    > template <typename T = double> class CVariable {
    > };
    >
    > template <typename T = double> class CSymbolic {
    > public:
    > CSymbolic(CVariable<T>){}
    > CSymbolic(){}
    > };
    >
    > template <typename T> CSymbolic<T> operator+(CSymbolic<T> a1, CSymbolic<T> a2) {
    > return CSymbolic();
    > }
    >
    > int main() {
    > CVariable<> x, y;
    > CSymbolic<> f1 = x+y; // problem here
    > }


    What are you trying to achieve? The problem is simple: there is no
    operator+ defined for operands of type CVariable<double>. The compiler
    is unable to use the operator+ that you defined for CSymbolic<> because
    when trying to figure out the type T to instantiate your operator+
    *template*, it cannot (shall not) consider conversions.

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jan 7, 2013
    #3
  4. On 1/7/2013 1:47 PM, Zhihao Yuan wrote:
    > On Monday, January 7, 2013 12:29:58 PM UTC-6, wrote:
    >> template <typename T> CSymbolic<T> operator+(CSymbolic<T> a1, CSymbolic<T> a2) {
    >> return CSymbolic();
    >> }

    >
    > Since CVariable<> is not convertible to CSymbolic,


    Uh... But it *is* convertible. Please look again, CSymbolic has a
    c-tor that takes CVariable as an argument.

    > this overload is
    > not selected. Make it convertible (you may need a forward
    > declaration), or have one more overload.
    >


    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jan 7, 2013
    #4
  5. Guest

    On Monday, January 7, 2013 7:49:23 PM UTC+1, Victor Bazarov wrote:
    > On 1/7/2013 1:29 PM, Thomas Grund wrote:
    >
    > > the following does not compile due to problems with the + operator. Thesame thing works without templates. How can I achive this?

    >
    > >

    >
    > > Thanks a lot,

    >
    > >

    >
    > > Thomas

    >
    > >

    >
    > >

    >
    > > template <typename T = double> class CVariable {

    >
    > > };

    >
    > >

    >
    > > template <typename T = double> class CSymbolic {

    >
    > > public:

    >
    > > CSymbolic(CVariable<T>){}

    >
    > > CSymbolic(){}

    >
    > > };

    >
    > >

    >
    > > template <typename T> CSymbolic<T> operator+(CSymbolic<T> a1, CSymbolic<T> a2) {

    >
    > > return CSymbolic();

    >
    > > }

    >
    > >

    >
    > > int main() {

    >
    > > CVariable<> x, y;

    >
    > > CSymbolic<> f1 = x+y; // problem here

    >
    > > }

    >
    >
    >
    > What are you trying to achieve? The problem is simple: there is no
    >
    > operator+ defined for operands of type CVariable<double>. The compiler
    >
    > is unable to use the operator+ that you defined for CSymbolic<> because
    >
    > when trying to figure out the type T to instantiate your operator+
    >
    > *template*, it cannot (shall not) consider conversions.
    >
    >
    >
    > V
    >
    > --
    >
    > I do not respond to top-posted replies, please don't ask


    I am playing around with symbolic calculus (see ginac-library). There is a typical structure of a base class from which several things are derived as sum, product, variable and so on. Then there is a wrapper (CSymbolic) whichwrapps all different types (contains pointer to base class). Everything works if the underlying numerical type is fixed (e.g. double). I want to makethis numerical type to be defined by the user to allow for instance interval arithmetic (interval type instead of double). Hope I made things clear.

    Thanks for solutions!

    Thomas
     
    , Jan 7, 2013
    #5
  6. Zhihao Yuan Guest

    On Monday, January 7, 2013 12:51:34 PM UTC-6, Victor Bazarov wrote:
    > Uh... But it *is* convertible. Please look again, CSymbolic has a
    > c-tor that takes CVariable as an argument.


    Oops, sorry.

    The problem is caused by function template deducution, conversion is
    not considered here.

    Enable it, in a quick and dirty way:

    template <template <typename> class C, typename T,
    typename = typename std::enable_if<
    std::is_convertible<C<T>, CSymbolic<T>>::value>::type>
    CSymbolic<T> operator+(C<T> a1, C<T> a2) {
    return {};
    }

    --
    Zhihao Yuan, ID lichray
    The best way to predict the future is to invent it.
    ___________________________________________________
    4BSD -- http://4bsd.biz/
     
    Zhihao Yuan, Jan 7, 2013
    #6
  7. Guest

    On Monday, January 7, 2013 8:46:19 PM UTC+1, Zhihao Yuan wrote:
    > On Monday, January 7, 2013 12:51:34 PM UTC-6, Victor Bazarov wrote: > Uh.... But it *is* convertible. Please look again, CSymbolic has a > c-tor thattakes CVariable as an argument. Oops, sorry. The problem is caused by function template deducution, conversion is not considered here. Enable it, in a quick and dirty way: template <template <typename> class C, typename T, typename = typename std::enable_if< std::is_convertible<C<T>, CSymbolic<T>>::value>::type> CSymbolic<T> operator+(C<T> a1, C<T> a2) { return {}; } --Zhihao Yuan, ID lichray The best way to predict the future is to invent it.. ___________________________________________________ 4BSD -- http://4bsd.biz/


    I have to learn this technique and will give it a try.

    Thank you very much!

    Thomas
     
    , Jan 8, 2013
    #7
  8. On Tuesday, January 8, 2013 2:29:58 AM UTC+8, wrote:
    > Hello,
    >
    >
    >
    > the following does not compile due to problems with the + operator. The same thing works without templates. How can I achive this?
    >
    >
    >
    > Thanks a lot,
    >
    >
    >
    > Thomas
    >
    >
    >
    >
    >
    > template <typename T = double> class CVariable {
    >
    > };
    >
    >
    >
    > template <typename T = double> class CSymbolic {
    >
    > public:
    >
    > CSymbolic(CVariable<T>){}
    >
    > CSymbolic(){}
    >
    > };
    >
    >
    >
    > template <typename T> CSymbolic<T> operator+(CSymbolic<T> a1, CSymbolic<T> a2) {
    >
    > return CSymbolic();
    >
    > }
    >
    >
    >
    > int main() {
    >
    > CVariable<> x, y;
    >


    OBJECT a= OBJECT b by the copy constructor first.

    Then it is trivial that
    a+=c for the object modifier +=.


    If the object size of b can't copy to a,
    pray for the old code can be morphed to use
    objects in the derived classes.




    > CSymbolic<> f1 = x+y; // problem here
    >
    > }
     
    88888 Dihedral, Jan 8, 2013
    #8
  9. 在 2013å¹´1月9日星期三UTC+8上åˆ11æ—¶25分14秒,Dan Stewart写é“:
    > On Mon, 07 Jan 2013 10:29:58 -0800, thomas.grund wrote:
    >
    >
    >
    > > Hello,

    >
    > >

    >
    > > the following does not compile due to problems with the + operator. The

    >
    > > same thing works without templates. How can I achive this?

    >
    > >

    >
    > > Thanks a lot,

    >
    > >

    >
    > > Thomas

    >
    > >

    >
    > >

    >
    > > template <typename T = double> class CVariable {

    >
    > > };

    >
    > >

    >
    > > template <typename T = double> class CSymbolic {

    >
    > > public:

    >
    > > CSymbolic(CVariable<T>){} CSymbolic(){}

    >
    > > };

    >
    > >

    >
    > > template <typename T> CSymbolic<T> operator+(CSymbolic<T> a1,

    >
    > > CSymbolic<T> a2) {

    >
    > > return CSymbolic();

    >
    > > }

    >
    > >

    >
    > > int main() {

    >
    > > CVariable<> x, y;

    >
    > > CSymbolic<> f1 = x+y; // problem here

    >
    > > }

    >
    >
    >
    > In this case when you call x + y you are trying to instantiate the
    >
    > function
    >
    >
    >
    > CSymbolic<double> operator+(CSymbolic<double> a1, CSymbolic<double> b1)
    >
    >
    >
    > with template argument CVariable<double>
    >
    >
    >
    > However, there are only 2 cases where conversion from a template argument
    >
    > to a template parameter is allowed:
    >
    >
    >
    > a) Template argument is a reference/pointer to T and template parameter
    >
    > is a reference/pointer to const T
    >
    >
    >
    > or
    >
    >
    >
    > b) Template argument is an array or function, in which case the template
    >
    > parameter is deduced to a pointer to the array or function type
    >
    >
    >
    > In this case you are trying instantiate the above function using a user-
    >
    > defined conversion from CVariable<double> to CSymbolic<double>, which
    >
    > templates won't allow, since the intended conversion doesn't fall under
    >
    > a) or b). Hope this helps.

    I am thinking there is no closure concept in C++
    operator reloading.

    Anyway, for fixed types languages, I don't think
    it is too difficult for various types.
     
    88888 Dihedral, Jan 9, 2013
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. MSG

    to cast or not to cast malloc ?

    MSG, Feb 6, 2004, in forum: C Programming
    Replies:
    38
    Views:
    1,121
    Dan Pop
    Feb 10, 2004
  2. EvilRix
    Replies:
    8
    Views:
    680
    Martin Dickopp
    Feb 14, 2004
  3. John Goche
    Replies:
    2
    Views:
    372
    Frederick Gotham
    Sep 4, 2006
  4. Pavel
    Replies:
    7
    Views:
    564
    Pavel
    Sep 19, 2010
  5. Qi
    Replies:
    2
    Views:
    690
Loading...

Share This Page