If one has a
template <class T>
class A{};
// global namespace, static storage duration
static constexpr A<int> a;
is it possible to deduce the type A<int> by passing a as a reference template param such as:
// This question asks to make the syntax in the following line compile:
static_assert(std::is_same<A<int>, typename GetReferenceType<a>::type>::value, "");
// I am aware the next line works, but it's not what I am looking for in this question
static_assert(std::is_same<A<int>, decltype(a)>::value, "");
// This is pseudo code of how this could work in theory
template <const T& RefT, class T> // I know this does not compile, but this shows what I want
struct GetReferenceType{ // which is automatically deduce type `T` without having to
using type = T; // write it out
};
An answer which explains why this is not possible in C++ is as welcome as a solution to make this syntax compile :) I am mostly asking out of curiosity, since basically everything else can be deduced in templates, but apparently not reference types.
This should also work, but does not fulfill the above syntax requirement:
template <class T>
constexpr auto GetReferenceTypeFunc(const T& t) -> T;
static_assert(std::is_same<A<int>, decltype(GetReferenceTypeFunc(a))>::value, "");
Why I want to do this
I am striving for the most concise syntax.
While Instantiate<decltype(a)> works, it's not ranking highly in the terseness scale, especially if a syntax like Instantiate<a> was possible.
Imagine a does not have a short type A<int> but instead something like
A<OmgWhyIsThisTypeNameSoLong>.
Then, if you want to instantiate a type with A<OmgWhyIsThisTypeNameSoLong>, you'd have to write:
Instantiate<A<OmgWhyIsThisTypeNameSoLong>>;
It just so happens that we already have a global object a, so it would be nice not to have to write that long type but instead Instantiate<a>.
There is of course the option of creating an alias using AOmg = A<OmgWhyIsThisTypeNameSoLong> but I would really like to get around spamming the namespace with another very similar name to A.
In C++20, you might do:
template <auto V>
struct GetReferenceType
{
using type = std::decay_t<decltype(V)>;
};
static_assert(std::is_same<A<int>, GetReferenceType<a>::type>::value);
but decltype seems sufficient.
Demo
// I not only want to deduce
A<int>but alsoint
So you probably want a trait like:
template <typename> struct t_parameter;
template <template <typename > class C, typename T> struct t_parameter<C<T>>
{
using type = T;
};
but simple alternative is to add info directly in A:
template <class T>
class A{
using value_type = T;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With