我看到decltype(x)在宏中使用,其中x是一个变量名,因为宏中不知道对象的类型。举例来说:
decltype(x)
x
decltype(x) y = expr;
我可以很容易地使用auto而不是decltype。那么,在哪些情况下,变量类型声明需要decltype而不是auto呢?
auto
decltype
sxpgvts31#
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描述的。在C++ FAQ中的Stroustrup。
wko9yo5t2#
当y的类型为:
y
expr
auto &
以及以下之一:
因此,例如,用decltype(*it)替换std::iterator_traits<RandomAccessIterator>::value_type可能是一种成功,尽管auto经常处理这种情况。主观判断是在“什么是困难的”、“什么是冗长的”和“什么是清楚的”这一点上作出的,但无论你在具体案件中如何作出这些判断,程序规则都是一样的。
decltype(*it)
std::iterator_traits<RandomAccessIterator>::value_type
k2arahey3#
当您希望y始终具有x的声明类型时。
jogvjijk4#
根据你的问题,
decltype(x) y总是使用与x声明的类型完全相同的类型声明y。特别是:
decltype(x) y
const int
int[100]
int f(int)
int&
int&&
当x具有以下类型时,auto y = x将使用以下类型声明y:
auto y = x
int
int*
int (*)(int)
[1]这里不能使用decltype,因为不能复制初始化数组。[2]这里不能使用decltype,因为不能初始化函数。[3]auto去掉引用的原因是C++没有引用类型的表达式!一旦初始化,引用的“引用性”就变得不可见。请注意,当decltype的参数不是id表达式时,decltype也会做一些完全不同的事情,我不会在这里讨论。
z4bn682m5#
当你的变量类型与被计算的表达式无关时。例如:
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
当然,这只是一个用例,还有更多。
hmtdttj46#
decltype比auto的通用性要高得多,并且可以随时替代它。因此,我认为decltype应该只在完全必要的情况下使用,所以如果auto产生错误的结果,你应该使用decltype。此外,你还不能在返回类型和参数中使用auto,所以你也可以在那里使用decltype。C14将显著增加auto的潜在用途,我猜C17将更进一步。因此,只有当您需要更改expr的结果类型时,才需要使用decltype另一件需要考虑的事情是,decltype并不是真正必要的,除非你正在编写库代码,auto对于日常编程来说是很好的,如果你想让你的代码更简洁,尽可能多地使用auto是否好还有待讨论,但是当处理像paddas这样的不可描述的类型时,它实际上是必要的。
6条答案
按热度按时间sxpgvts31#
decltype
在你需要返回一些未知类型时变得很方便,这些类型在编译过程中被评估:此外,如果你不喜欢引用处理输出的方式,那么你也可以使用后来指定的返回类型(也可以使用
decltype
):所有这一切,以及更多,都是由B描述的。在C++ FAQ中的Stroustrup。
wko9yo5t2#
当
y
的类型为:expr
类型不同(或可能不同)。如果是相同的,那么auto
将更简洁。auto &
或auto
可以表达的expr
类型的其它修改。以及以下之一:
decltype
可以保存您定义的类型。因此,例如,用
decltype(*it)
替换std::iterator_traits<RandomAccessIterator>::value_type
可能是一种成功,尽管auto
经常处理这种情况。主观判断是在“什么是困难的”、“什么是冗长的”和“什么是清楚的”这一点上作出的,但无论你在具体案件中如何作出这些判断,程序规则都是一样的。
k2arahey3#
当您希望
y
始终具有x
的声明类型时。jogvjijk4#
根据你的问题,
decltype
。auto
。decltype(x) y
总是使用与x
声明的类型完全相同的类型声明y
。特别是: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&&
。当
x
具有以下类型时,auto y = x
将使用以下类型声明y
:x
的类型为const int
,则y
的类型为int
。也就是说,auto
去掉顶级cv限定符。x
的类型为int[100]
,则y
的类型为int*
。也就是说,auto
执行数组到指针的转换。[1]第一章x
的类型为int f(int)
,则y
的类型为int (*)(int)
。也就是说,auto
执行函数到函数指针的转换。[二]《中国日报》x
的类型为int&
或int&&
,则y
的类型为int
。也就是说,auto
删除引用。[1]这里不能使用
decltype
,因为不能复制初始化数组。[2]这里不能使用
decltype
,因为不能初始化函数。[3]
auto
去掉引用的原因是C++没有引用类型的表达式!一旦初始化,引用的“引用性”就变得不可见。请注意,当
decltype
的参数不是id表达式时,decltype
也会做一些完全不同的事情,我不会在这里讨论。z4bn682m5#
当你的变量类型与被计算的表达式无关时。
例如:
当然,这只是一个用例,还有更多。
hmtdttj46#
decltype
比auto
的通用性要高得多,并且可以随时替代它。因此,我认为decltype
应该只在完全必要的情况下使用,所以如果auto
产生错误的结果,你应该使用decltype。此外,你还不能在返回类型和参数中使用auto
,所以你也可以在那里使用decltype
。C14将显著增加auto
的潜在用途,我猜C17将更进一步。因此,只有当您需要更改expr
的结果类型时,才需要使用decltype
另一件需要考虑的事情是,
decltype
并不是真正必要的,除非你正在编写库代码,auto对于日常编程来说是很好的,如果你想让你的代码更简洁,尽可能多地使用auto
是否好还有待讨论,但是当处理像paddas这样的不可描述的类型时,它实际上是必要的。