我看到decltype(x)
在宏中使用,其中x
是变量名,因为在宏内部不知道对象的类型。
例如:
decltype(x) y = expr;
我可以轻松使用auto
代替decltype
。那么,变量类型声明而不是decltype
需要auto
的情况是什么?
答案 0 :(得分:18)
当所需的y
类型为:
expr
的类型不同(或可能不同)。如果它是相同的那么auto
会更简洁。auto &
或expr
可以表达的auto
类型的其他修改。以及以下之一:
decltype
来保存您定义的类型。因此,例如,将std::iterator_traits<RandomAccessIterator>::value_type
替换为decltype(*it)
可能会获胜,但auto
通常会处理此类情况。
主观判断进入“困难”,“什么是啰嗦”和“什么是明确”这一点,但无论你如何在特定情况下做出判断,程序规则都可以相同。
答案 1 :(得分:17)
当您希望y
始终拥有声明的x
类型时。
答案 2 :(得分:17)
decltype
会变得很方便:
template<class A, class B>
void MultiplyAB(A a, B b, decltype(a*b)& output)
{
output = a * b;
}
此外,如果您不喜欢引用处理输出的方式,那么您还可以使用迟到的返回类型(并使用decltype
):
template<class A, class B>
auto MultiplyAB(A a, B b) -> decltype(a*b)
{
return a * b;
}
所有这些,以及更多,由B. Stroustrup在C++ FAQ中描述。
答案 3 :(得分:8)
在您的问题中,
如果您想要一个与原始变量具有完全相同类型的新变量,则应使用decltype
。
如果您希望将某个表达式的值分配给新变量,并且您希望或需要推断其类型,则应使用auto
。
decltype(x) y
始终声明y
与声明类型x
的类型完全相同。特别是:
x
的类型为const int
,则y
的类型为const int
。x
的类型为int[100]
,则y
的类型为int[100]
。x
的类型为int f(int)
,则y
的类型为int f(int)
。是的,这实际上声明了另一个与原始类型相同的函数。x
的类型为int&
,则y
的类型为int&
;如果x
的类型为int&&
,则y
的类型为int&&
。auto y = x
具有以下类型时, y
会使用以下类型声明x
:
x
的类型为const int
,则y
的类型为int
。也就是说,auto
剥离顶级cv限定符。 x
的类型为int[100]
,则y
的类型为int*
。也就是说,auto
执行数组到指针转换。 [1] x
的类型为int f(int)
,则y
的类型为int (*)(int)
。也就是说,auto
执行函数指针转换功能。 [2] x
的类型为int&
或int&&
,则y
的类型为int
。也就是说,auto
会删除引用。 [1]你不能在这里使用decltype
,因为你无法复制初始化数组。
[2]你不能在这里使用decltype
,因为你无法初始化一个函数。
[3] auto
剥离引用的原因是C ++没有引用类型的表达式!初始化后,引用的“引用”将变为不可见。
请注意,当decltype
的参数不是id-expression时,{{1}}也会做一些完全不同的事情,我不会在这里讨论。
答案 4 :(得分:7)
每当您的变量类型与正在评估的表达式无关时。
E.g:
struct Bar
{
Bar(int) {} // implicitly constructable
}
struct Bar2
{
Bar2(int) {} // implicitly constructable
}
struct Foo
{
static Bar var;
}
struct Foo2
{
static Bar2 var;
}
template <typename T>
void dummy()
{
decltype(T::var) myVar = 42;
}
dummy<Foo>(); // myVar is of type Bar1
dummy<Foo2>(); // myVar is of type Bar2
auto myAutoVar = 42; // type is int
当然这只是一个用例,还有更多用例。
答案 5 :(得分:6)
decltype
明显更加通用auto
,并且可以随时用它代替它。因此,我认为decltype
仅应用于完全必要的情况是非常安全的,因此如果auto
产生错误的结果,则应使用decltype。此外,您还不能在返回类型和参数中使用auto
,因此您也可以在其中使用decltype
。 C ++ 14将显着增加auto
的潜在用途,我猜想c ++ 17会更进一步。因此,只有当您需要更改decltype
expr
的情况
另一件需要考虑的事情是,除非你正在编写库代码,否则decltype
并不是必需的,如果你想让你的代码更简洁,那么auto对于日常编程很有用,它可以用来讨论尽可能多auto
是好的,但在使用像lambdas这样的不可言说的类型时,这几乎是必要的。