Reputation: 10911
I have a type T
that has a member function fn
with a return type RT
.
I have a template that takes T
and RT
as parameters. I'd like to alias this template class so that my code isn't so ugly and hard to read. How would I accomplish that?
template <typename X, typename Y>
struct I
{};
struct T
{
int& fn(int);
};
So I want to alias this or something like this type so I can write a function like this:
template <typename C>
I< typename std::remove_reference<std::decltype(std::declval(C).fn(0))>::type, C> fn(C& c)
{
return I< typename std::remove_reference<std::decltype(std::declval(C).fn(0))>::type, C>();
}
But with less mess. I've not used std::decltype
before, so I'm not even sure if I'm using it right as I was getting errors.
I was thinking about using a function like that and doing a decltype on it, but I was having some difficulty with it and I'd like it to look cleaner too.
Upvotes: 0
Views: 545
Reputation: 48457
decltype()
is a built-in operator, not a function from the std
namespace like std::declval<T>()
.
If you want to shorten the syntax with an alias template, you can declare one as shown below:
#include <type_traits>
template <typename C>
using IT = I<C, typename std::remove_reference<decltype(std::declval<C&>().fn(0))>::type>;
template <typename C>
IT<C> fn(C& c)
{
return IT<C>(&c, c.fn(1));
}
Since the above code fails to compile successfully in VC++ for an unknown reason, you can instead create an alias template that queries the result type of a helper function that you already have:
template <typename C>
I<C, typename std::remove_reference<decltype(std::declval<C&>().fn(0))>::type> test();
template <typename C>
using IT = decltype(test<C>());
template <typename C>
IT<C> fn(C& c)
{
return IT<C>(&c, c.fn(1));
}
Upvotes: 1