• Advertisement
Sign in to follow this  

c++ templates - is this possible?

This topic is 4590 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

say i have a class like this:
template<class num_t>
class quantity
{
public:
    template<class result_num_t, class other_num_t>
    quantity<result_num_t> operator*(const other_num_t& other)
    {
         return quantity<result_num_t>(_value * other.getValue());
    }
    num_t getValue(){return _value;};

private:
    num_t _value;
};



Is there any way to get the compiler to deduce the return type of operator* ? Now I believe I could write:

quantity<A> a;
quantity<B> b;

quantity<ABproduct> result = a.operator*<ABproduct>(b);



but the syntax is horrible and I have to explicitly state the return type, which isn't always convienient (such as in compound statements). Note: I've got boost installed and I'm prepared to delve as deeply into template 'magic' as is needed if this is possible. [Edited by - Nitage on July 29, 2005 9:42:04 AM]

Share this post


Link to post
Share on other sites
Advertisement
No, it's not possible. C++ will not do type deduction on the return type of a template function.

Edit: what you can do is return a type the relies on both types, like make a template type
template <typename A, typename B> ProductType

and return that or a type typedefed inside that type.

Share this post


Link to post
Share on other sites
Any way around this or recommendations on how I could improve the function?

At the minute I'm just using the tpye of the left hand argument.

As an aside, is there a proposal to change this in C++0x?

Share this post


Link to post
Share on other sites
AFAIK, there are no plans to change this in the next version of the C++ standard.

Share this post


Link to post
Share on other sites
Ok - slightly different question:

If I have two types, say A and B, is there any expression which gives me the return type of A*B?

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
AFAIK, there are no plans to change this in the next version of the C++ standard.


I thought the 'auto' keyword was being thought about for this exact reason?

auto iter = myvec.begin();

The compiler has enough information, it just doesn't expose it through the language right now. This is one of the proposals that had a lot of support last time I checked. Has this changed? Also I haven't read it entirely, so I'm not sure if it includes templated functions or not, but as the types are replaced at compile time, I can't see how template functions provide any more of a problem that a normal function.

Share this post


Link to post
Share on other sites
Quote:
Original post by Nitage
Ok - slightly different question:

If I have two types, say A and B, is there any expression which gives me the return type of A*B?


I'm using an older version of something that was in the boost sandbox for that, but I think it's been replaced by boost::mpl. I currently use something that looks like this:

boost::result_of_plus<A, B>::type
boost::result_of_multiplies<A, B>::type

and you can specialize the result_of structs for your own custom types as well. If you'd like the header I can send it to you, but it did not make it into any official boost release. Again, I think the functionality got folded into boost::mpl. Someone else may know for sure.

Here's an example (It's pretty ugly though).

template <typename LHS, typename RHS>
inline typename boost::result_of_plus<LHS, RHS>::type
operator +(const LHS &lhs, const RHS &rhs)
{
typename boost::result_of_plus<LHS, RHS>::type nrv(lhs);
nrv += rhs;
return nrv;
}


Share this post


Link to post
Share on other sites
Quote:
Original post by mfawcett
Quote:
Original post by SiCrane
AFAIK, there are no plans to change this in the next version of the C++ standard.


I thought the 'auto' keyword was being thought about for this exact reason?

auto iter = myvec.begin();



the OP doesn't want the assigned-variable to be dependent on the function's return-type, he wants the function's return type to be dependent on the assigned-variable. more like:

auto my_function(int a)
{ ... }

Object b = my_function(3);

where my_function would somehow know to return a type 'Object'.

even if possible through some magic, i believe this would violate the more fundamental rule where a "over-loaded function cannot differ by only its return type."

illone

Share this post


Link to post
Share on other sites
Quote:
Original post by illone

the OP doesn't want the assigned-variable to be dependent on the function's return-type, he wants the function's return type to be dependent on the assigned-variable. more like:


Yes, of course. My misunderstanding.

Share this post


Link to post
Share on other sites
When num_t, result_num_t, and other_num_t are supposed to be the same you can ditch result_num_t, and other_num_t and just use num_t.
It wouldn't even need to be a templated function, only a templated class.

But if you want to be able to multiply a 'quantity' by a 'foo_bar' then just write an explicit operator function for it and make foo_bar a friend, again without templates, making the return type obvious.
So basically you have to specify a * operator function for each type you can multiply 'quantity' by.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
AFAIK, there are no plans to change this in the next version of the C++ standard.

Actually, this is one of the main reasons for the proposed typeof keyword, which many compilers already support, and which boost will most-likely have a macro for in 1.34 which is capable of working with some compilers that don't even directly support typeof (it may possibly be in the 1.33 release on august 1st, but I don't believe it was accepted yet).

Share this post


Link to post
Share on other sites
Is the result_num type related to the othet type? I.E If you use type B in other.. will you always imply in using teh same type A in result?


If so you can hide this type relationship in a type traits class and make soemthing like:

template<class oth>
Traits<oth>::multResult operator*(const oth& o){ ...}

Share this post


Link to post
Share on other sites
am I missing something fundamental in the original post or do you simply want to do this:

int main(void)
{
quantity<int> a(21);
quantity<float> b(2);
quantity<double> result = a * b;
std::cout << "a = " << a.value() << " b = " << b.value() << " a * b = " << result.value() << "\n";
}

here's the stuff to make it work:

template <typename T>
class quantity
{
public:
quantity(const T& value): m_value( value){}
const T& value(void) const { return m_value;}

template <typename U,typename V>
struct mul
{
mul(const quantity<U> &l, const quantity<V> &r): left( l), right( r){}
const quantity<U> &left;
const quantity<V> &right;

template <typename R>
operator quantity<R>() const { return quantity<R>( left.value() * right.value());}
};

template <typename U>
mul<T,U> operator *(const quantity<U> &other){ return mul<T,U>( *this, other);}

private:
T m_value;
};


Share this post


Link to post
Share on other sites
Quote:

the OP doesn't want the assigned-variable to be dependent on the function's return-type, he wants the function's return type to be dependent on the assigned-variable. more like:

auto my_function(int a)
{ ... }

Object b = my_function(3);

where my_function would somehow know to return a type 'Object'.


I want the return type to be dependent on the parameters, not the type of the assigned variable:

say I want to multiply a quanity<int>; and a quantity<float>; - the return type of the templated operator * for quantity should set it's return type to quantity<x> where x is the return type of int*float.


Quote:

I'm using an older version of something that was in the boost sandbox for that, but I think it's been replaced by boost::mpl. I currently use something that looks like this:

boost::result_of_plus<A, B>::type
boost::result_of_multiplies<A, B>::type

and you can specialize the result_of structs for your own custom types as well. If you'd like the header I can send it to you, but it did not make it into any official boost release. Again, I think the functionality got folded into boost::mpl. Someone else may know for sure.


Thanks, that's exactly what I'm looking for. It would be very helpful if you could send me that header.

[Edited by - Nitage on August 1, 2005 5:36:03 AM]

Share this post


Link to post
Share on other sites
No need to send me that header. result_of is in boost/utility.hpp

Thanks for your help.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement