【发布时间】:2020-03-27 07:13:19
【问题描述】:
如果有一个
template <class T>
class A{};
// global namespace, static storage duration
static constexpr A<int> a;
是否可以通过传递a 作为参考模板参数来推断类型A<int>,例如:
// 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 非常相似的名称向命名空间发送垃圾邮件。
【问题讨论】:
-
您是否尝试使用变量名来生成类型,但没有使用
decltype? -
是的。我想使用变量名作为类型的“速记”。 (想象一下 A
真的很笨拙。 -
我对您需要解决的实际和潜在问题更加好奇。为什么你需要做这样的事情?请edit您的问题直接询问该潜在问题(否则它是XY problem),还请明确说明您可能有的ant要求(如您的“语法要求”)。您可以向我们展示您尝试过的方法,并告诉我们它是如何不起作用的。如果只是单纯的好奇,那没关系,但请告诉我们。
-
要将引用作为模板参数传递,您传递的事物需要具有静态存储持续时间。因此,即使您完成这项工作,它也不会很有用。
-
你能解释一下
Instantiate<decltype(a)>有什么问题吗