0
votes

How can I get the return type of an implicit conversion of an object?

struct Bar {
  operator int() const {
    return 0;
  }
};

// std::result_of<Bar>::type value; ???
// std::result_of<Bar::operator ??? >::type value;

I could use:

std::is_convertible<Bar, int>::value

but is_convertible is also true for float, unsigned int etc.... I would like to have the exact type.

Edit: Because my question seems unclear, why I want to know the implicit conversion type. Please think a step further to template classes. So i do not know Bar at all...

template<typename T, typename Sfinae = void>
struct ImplicitType
{
  static_assert(sizeof(T) != sizeof(T), "Unknown type.");
};

template<typename T>
struct ImplicitType<T,
    typename std::enable_if<std::is_convertible<T, int>::value && std::is_class<T>::value>::type>
{
  using type = int;
};

template<typename T>
struct ImplicitType<T,
    typename std::enable_if<std::is_convertible<T, float>::value && std::is_class<T>::value>::type>
{
  using type = int;
};

struct Foo
   operator float() const {
     return 0.0f;
   }
};

struct Bar {
   operator int() const {
     return 0;
   }
};

ImplicitType<Foo> r; // <--- ambiguous template instantiation
ImplicitType<Bar> r; // <--- ambiguous template instantiation

For Foo I would like to get float. For Bar int.

But because I can define one or more implicit conversions for class, it gets tricky.

struct FooBar {
  operator float() const {
     return 0;
   }

   operator int() const {
     return 0;
   }
};

Not working live example.

So all in all it is not possible to get the right implicit conversation type of a class?

1
decltype() and auto? - Vasiliy Soshnikov
decltype<Bar()> is Bar and auto f = Bar; is Bar. - Viatorus
Bar b; decltype((int)b) x = (int)b; - Vasiliy Soshnikov
Implicit conversion to what? In your case it is clear, but what would be the desired result if there were more than 1 conversion operator? - anderas
@Viatorus yes, or you need store type inside class i.e. Bar { typedef int my_conv_type; } - Vasiliy Soshnikov

1 Answers

-1
votes
#include <iostream>
#include <typeinfo>
struct Bar {
    operator int() const {
        return 0;
    }
    operator double() const {
        return 0.0;
    }

    struct Foo {

    };
    operator Foo() const {
        return Foo();
    }
};
int main() {
    std::cout << typeid( decltype((int)Bar()) ).name();
    std::cout << std::endl;
    std::cout << typeid( decltype((double)Bar()) ).name();
    std::cout << std::endl;
    std::cout << typeid( decltype((Bar::Foo)Bar()) ).name();
    std::cout << std::endl;
}

According to that fact, that function Bar::operator int() is a member function of class Bar, you guarantee, that there is a this reference for it, so that's why I provide a default object Bar() for all the stuff.

The result is:

i
d
N3Bar3FooE