推导参考模板参数的类型

时间:2020-03-27 07:13:19

标签: c++ c++11 c++14 c++17

如果有一个

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非常相似的名称空间来发送垃圾邮件。

1 个答案:

答案 0 :(得分:2)

在C ++ 20中,您可以这样做:

template <auto V>
struct GetReferenceType
{
    using type = std::decay_t<decltype(V)>;  
};

static_assert(std::is_same<A<int>, GetReferenceType<a>::type>::value);

但是decltype似乎足够。

Demo

//我不仅要推论A<int>,而且要推论int

所以您可能想要像这样的特征:

template <typename> struct t_parameter;

template <template <typename > class C, typename T> struct t_parameter<C<T>>
{
    using type = T;    
};

但简单的替代方法是直接在A中添加信息:

template <class T>
class A{
    using value_type = T;
};