【问题标题】:Deduce type of reference template parameter推断引用模板参数的类型
【发布时间】:2020-03-27 07:13:19
【问题描述】:

如果有一个

template <class T>
class A{};

// global namespace, static storage duration
static constexpr A<int> a;

是否可以通过传递a 作为参考模板参数来推断类型A&lt;int&gt;,例如:

// 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&lt;decltype(a)&gt; 有效,但它在简洁性方面的排名并不高,尤其是如果像Instantiate&lt;a&gt; 这样的语法是可能的。

想象一下 a 没有短类型 A&lt;int&gt; 而是类似 A&lt;OmgWhyIsThisTypeNameSoLong&gt;.

那么,如果你想用A&lt;OmgWhyIsThisTypeNameSoLong&gt; 实例化一个类型,你必须这样写:

Instantiate<A<OmgWhyIsThisTypeNameSoLong>>;

碰巧我们已经有一个全局对象a,所以不用写那个长类型而是Instantiate&lt;a&gt;就好了。

当然可以选择创建别名 using AOmg = A&lt;OmgWhyIsThisTypeNameSoLong&gt;,但我真的很想避免使用与 A 非常相似的名称向命名空间发送垃圾邮件。

【问题讨论】:

  • 您是否尝试使用变量名来生成类型,但没有使用decltype
  • 是的。我想使用变量名作为类型的“速记”。 (想象一下 A 真的很笨拙。
  • 我对您需要解决的实际和潜在问题更加好奇。为什么你需要做这样的事情?请edit您的问题直接询问该潜在问题(否则它是XY problem),还请明确说明您可能有的ant要求(如您的“语法要求”)。您可以向我们展示您尝试过的方法,并告诉我们它是如何不起作用的。如果只是单纯的好奇,那没关系,但请告诉我们。
  • 要将引用作为模板参数传递,您传递的事物需要具有静态存储持续时间。因此,即使您完成这项工作,它也不会很有用。
  • 你能解释一下Instantiate&lt;decltype(a)&gt;有什么问题吗

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


【解决方案1】:

在 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&lt;int&gt;还要推演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;
};

【讨论】:

    猜你喜欢
    • 2023-03-31
    • 2015-02-06
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多