Если имеется
template <class T>
class A{};
// global namespace, static storage duration
static constexpr A<int> a;
, можно ли вывести тип A<int>
, передав a
в качестве параметра эталонного шаблона, например:
// 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
};
Ответ который объясняет, почему это невозможно в C ++, приветствуется как решение для компиляции этого синтаксиса :) Я в основном спрашиваю из любопытства, поскольку в принципе все остальное можно вывести в шаблонах, но, очевидно, не в ссылочных типах.
Это также должно работать, но не удовлетворяет вышеуказанному синтаксическому требованию:
template <class T>
constexpr auto GetReferenceTypeFunc(const T& t) -> T;
static_assert(std::is_same<A<int>, decltype(GetReferenceTypeFunc(a))>::value, "");
Почему я хочу это сделать
Я стремлюсь к самому краткому синтаксис. Несмотря на то, что Instantiate<decltype(a)>
работает, он не имеет высокого рейтинга по шкале краткости, особенно если возможен такой синтаксис, как Instantiate<a>
.
Представьте себе, a
не имеет короткого типа A<int>
, а вместо этого что-то вроде A<OmgWhyIsThisTypeNameSoLong>
.
Затем, если вы хотите создать экземпляр типа с помощью A<OmgWhyIsThisTypeNameSoLong>
, вам нужно написать:
Instantiate<A<OmgWhyIsThisTypeNameSoLong>>;
Так уж получилось, что у нас уже есть глобальный объект a
, поэтому было бы неплохо не писать этот длинный тип, а вместо этого Instantiate<a>
.
Конечно, есть возможность создать псевдоним using AOmg = A<OmgWhyIsThisTypeNameSoLong>
, но я бы очень хотел обойтись рассылка спама в пространстве имен с другим именем, очень похожим на A
.