decltype 不会推断 const 对象的 const 成员
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 Stages,那么为什么 self.member 不被推导为 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
限定符。
您可以在 cpp首选项页面上找到更正式(和准确)的解释decltype(...)
.
顺便说一下,请考虑通过模板参数而不是std::function
传递回调。后者不是零成本抽象 - 它是一个使用类型擦除的重量级包装器,应将其使用量降至最低。
template <typename Self, typename F>
static void forall_chains(Self& self, F&& fun){ /* ... */ }
我写了一篇关于这个主题的文章:将函数传递给函数。
是的,确实如此。decltype
有一个decltype(self.mutating_chains)
的特殊情况(强调我的):
如果参数是无括号的 id 表达式或无括号的类成员访问表达式,则 decltype 将生成此表达式命名的实体的类型。
因此,您将获得声明self.mutating_chains
的实际类型,即Chains
。
添加括号时,您将回退到一般情况,该情况实际上计算表达式的类型,在const Self
的情况下,表达式按预期const Chains &
:
如果参数是
T
和 a) 的任何其他表达式 [...]
b) 如果表达式的值类别是左值,则 decltype 产生T&
;
c) [...]
- 被解释为低级别const的const对象的地址
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- Google Or-Tools Glop:如何创建指向 const 对象的指针数组?
- 我们可以有一个 setter 成员函数作为从 const 对象引用的 const 吗?
- "this"指向的对象是否与 const 对象相同?
- 从 const 对象访问非 const 方法
- 将非 const 对象用于 const 参数
- 如何键入用于const对象的自定义io操纵器
- 哪个 const 与哪个引用将更改参数并创建一个 const 对象?
- 无法在返回中转换 const 对象
- 接受对 const 对象的引用但没有 r 值的函数
- 当我调用 main 中使用 const 对象的 const 函数时,不断出现错误
- 在 const 对象上调用非 const 函数
- 正确的方法通过巨大的const对象的向量
- 如何重载 const 对象的 [],以便值赋值不会导致编译错误
- 相互引用的 Const 对象
- 析构函数是否可以在 const 对象上调用非 const 函数
- decltype 不会推断 const 对象的 const 成员
- 防止const函数被调用非const对象
- constexpr引用非const对象