user13830821
user13830821

Reputation:

Can a function return a type?

I was wondering if there was any way to do something like this in C++:

$(some typename) func() {
    if (/*condition*/) return int;
    else return bool;
}

Edit: I think I wasn't clear enough. I was wondering if you could say something like this: func() var = /*something*/. Basically, the function is returning something like int or bool (the type, not a value of that type).

Upvotes: 1

Views: 211

Answers (2)

Evgeny S.
Evgeny S.

Reputation: 858

There is a cute library Boost.Hana that can be used for computations on types in C++ metaprogramming.

With Boost.Hana a function returning an object representing the C++ type could look like this:

auto func()
{
   return hana::if_(
      /*constexpr condition*/,
      hana::type_c<int>,
      hana::type_c<bool>
   );
}

Upvotes: 0

Anonymous1847
Anonymous1847

Reputation: 2598

A function cannot choose which type to return at runtime; it must have a definite return type at compile time. What you can use instead is a template with a member type. You will need to use template metaprogramming for this. As an example, here is an adapter template that makes a type T into its const pointer form:

template <typename T>
struct make_const_ptr {
    using type = const T*;
};

template <typename>
using make_const_ptr_t<T> = typename make_const_ptr<T>::type

This is essentially a "function" that returns a type, in the sense that you can "call" it by writing make_const_ptr_t<T>. You can do a bunch more operations on types using template metaprogramming: https://www.geeksforgeeks.org/template-metaprogramming-in-c/ .

Plus, you said in your comments that you wanted to use this to choose which template function to use on a polymorphic type. An even better way to do this is to use a virtual function; doing different things for different polymorphic types is the whole point of virtual functions:

template <typename T>
void template_function(const T& obj) {
    // ...
}

class Base {
    // ...
    virtual void do_template_function() = 0;
};

class D : public Base {
    virtual void do_template_function() {
        template_function<D>(*this);
    }
};

class E : public Base {
    virtual void do_template_function() {
        template_function<E>(*this);
    }
};

void f(Base* obj) {
    // ...
    obj->do_template_function();
    // ...
}

Upvotes: 3

Related Questions