template, cast, and operator

T

thomas.grund

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
}
 
Z

Zhihao Yuan

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.
 
V

Victor Bazarov

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
 
V

Victor Bazarov

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
 
T

thomas.grund

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 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
 
Z

Zhihao Yuan

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 {};
}
 
T

thomas.grund

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

Thank you very much!

Thomas
 
8

88888 Dihedral

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.
 
8

88888 Dihedral

在 2013å¹´1月9日星期三UTC+8上åˆ11æ—¶25分14秒,Dan Stewart写é“:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top