Reputation: 1892
I have a functor, I want the return type to be deduced automatically. How can I do this?
template <typename _ScalarL, typename _ScalarR>
struct Multi
{
DEDUCEDTYPE operator()(_ScalarL input1, _ScalarR input2) const
{
return input1 * input2;
}
};
int main(){
Multi<int, double> mt;
mt(1,2.0);
}
how to get the DEDUCEDTYPE
automatically?
Upvotes: 2
Views: 1033
Reputation: 13988
Well I believe that before c++11 you are doomed to provide deduction by hand... You could create helper struct with specializations for that:
template <typename A, typename B>
struct deduce { };
template <>
struct deduce<int, double> {
typedef double type;
};
template <typename ScalarL, typename ScalarR>
struct Multi
{
typename deduce<ScalarL, ScalarR>::type operator()(ScalarL input1, ScalarR input2) const
{
return input1 * input2;
}
};
int main(){
Multi<int, double> mt;
mt(1,2.0);
}
Edit:
The more general way of doing it would invoke however creating the hierarchy of priorities of the types that should be considered while deducing result type. Exemplary code:
#include <iostream>
template <typename T>
struct MoreGeneralNumber { };
template <>
struct MoreGeneralNumber<long>: MoreGeneralNumber<int> {};
template <>
struct MoreGeneralNumber<float>: MoreGeneralNumber<long> {};
template <>
struct MoreGeneralNumber<double>: MoreGeneralNumber<float> {};
typedef char (&yes)[1];
typedef char (&no)[2];
template <bool L, bool R, typename LT, typename RT>
struct MoreGeneral { };
template <bool R, typename LT, typename RT>
struct MoreGeneral<true, R, LT, RT> {
typedef LT type;
};
template <typename LT, typename RT>
struct MoreGeneral<false, true, LT, RT> {
typedef RT type;
};
template <typename B, typename D>
struct Host
{
operator B*() const;
operator D*();
};
template <typename B, typename D>
struct is_base_of
{
template <typename T>
static yes check(D*, T);
static no check(B*, int);
static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);
};
template <typename L, typename R>
struct Deduce: MoreGeneral<is_base_of<MoreGeneralNumber<R>, MoreGeneralNumber<L> >::value,
is_base_of<MoreGeneralNumber<L>, MoreGeneralNumber<R> >::value, L, R > {
};
template <typename ScalarL, typename ScalarR>
struct Multi
{
typename Deduce<ScalarL, ScalarR>::type operator()(ScalarL input1, ScalarR input2) const
{
return input1 * input2;
}
};
int main() {
Multi<int, double> mt;
std::cout << mt(1, 2.5) << std::endl;
}
Upvotes: 3
Reputation: 70094
how to get the DEDUCEDTYPE automatically [with c++03]?
Automatic type deduction is not possible with C++03. As mentioned in other answer, you may have to manually create your own deducing specializations.
For C++11/C++14:
// For C++14, simply `auto` is enough
auto operator()(_ScalarL input1, _ScalarR input2) const
#if __cplusplus < 201402L
-> decltype(input1 * input2) // required for C++11
#endif
Upvotes: 3