![](/img/trans.png)
[英]'const decltype((a))' does not declare a const reference?
[英]decltype does not deduce const members for const objects
#include <type_traits>
#include <functional>
struct Chains
{};
struct Stages
{
Chains mutating_chains;
Chains sideffect_chains;
Chains write_chains;
void forall_chains(const std::function<void(Chains & chain)> & fun)
{
forall_chains(*this, fun);
}
void forall_chains(
const std::function<void(const Chains & chain)> & fun) const
{
forall_chains(*this, fun);
}
template <typename Self>
static void forall_chains(
Self & self,
const std::function<void(decltype(self.mutating_chains) & chain)> & fun)
{
fun(self.mutating_chains);
fun(self.sideffect_chains);
fun(self.write_chains);
}
};
显然有一些我无法用decltype
理解的东西。 因为根据编译器抛出的错误消息,Self被推断为const阶段,那么为什么self.member不推导为const成员? 另外如何使它正常工作,演绎const对象的const成员? 我在表达式decltype((self.mutating_chains))
添加了括号,并且通过了编译,但我不确定这是否正确。
f.cpp: In instantiation of ‘static void Stages::forall_chains(Self&, const std::function<void(decltype (self.mutating_chains)&)>&) [with Self = const Stages; decltype (self.mutating_chains) = Chains]’:
f.cpp:150:33: required from here
f.cpp:158:33: error: no match for call to ‘(const std::function<void(Chains&)>) (const Chains&)’
fun(self.mutating_chains);
我在表达式
decltype((self.mutating_chains))
添加了括号,并且通过了编译,但我不确定这是否正确。
是的,在这种情况下,这是正确的做法。 简而言之, decltype(x)
为您提供声明的x
类型 ,它不依赖于表达式的值类别。
对于类型为T
的左值表达式 x
, decltype((x))
代替产生T&
,在您的情况下,正确地应用了const
限定符。
您可以在decltype(...)
的cppreference页面上找到更正式(和准确)的解释。
顺便说一句,请考虑通过模板参数而不是std::function
传递回调。 后者不是零成本抽象 - 它是一个使用类型擦除的重量级包装器,其使用应该最小化。
template <typename Self, typename F>
static void forall_chains(Self& self, F&& fun){ /* ... */ }
我写了一篇关于这个主题的文章: 将函数传递给函数 。
确实是的。 decltype
有一个特殊的decltype(self.mutating_chains)
案例decltype(self.mutating_chains)
(强调我的):
如果参数是未加密码的id-expression或未加括号的类成员访问表达式 ,则decltype将生成此表达式命名的实体的类型。
因此,您将获得已声明self.mutating_chains
的实际类型,即Chains
。
当你添加括号时,你会回到一般情况,它实际上会计算表达式的类型,在const Self
的情况下,它是const Chains &
预期的:
如果参数是
T
类型的任何其他表达式,则
一种) [...]
b)如果表达式的值类别是左值,则decltype产生T&
;
C) [...]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.