Pat*_*ght 2 c++ volatile member-functions explicit-object-parameter
假设我有以下非常简单的类:
class A
{
public:
static constexpr A make() { return A{}; }
constexpr A() : _v(0) {}
constexpr A& setV(int v) { _v = v; return *this; }
private:
int _v;
};
Run Code Online (Sandbox Code Playgroud)
如果我尝试按如下方式使用它:
int main()
{
volatile A a1;
a1.setV(10);
//OR
//The optimizer will optimize this chain of constexpr calls into a single "store" instruction
a1 = A::make().setV(10); //More chaining here
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该代码将无法编译。
我理解为什么这是真的,基于:定义易失性类对象
我知道解决方案是添加一个额外的方法,如下所示:
class A
{
public:
constexpr A() : _v(0) {}
volatile A& setV(int v) volatile { _v = v; return *this; }
constepxr A& setV(int v) { _v = v; return *this; }
private:
int _v;
};
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我知道如果不使用它,返回易失性引用会发出警告。
我的问题是,在这种情况下有什么方法可以避免代码重复吗?的两种实现始终setV是相同的。因此,如果我添加/更改更多方法,我必须维护它们,如果它们不是那么微不足道,这可能会变得混乱。唯一的区别是类型限定符之一......
由于评论中提到了这一点,我想我会注意到我在这里需要易失性,因为我试图最终在嵌入式系统上实现硬件外设寄存器访问的“类覆盖”。
在 C++23 中,您可以使用显式对象参数(也称为推导 this)来实现此目的:
class A
{
public:
A() : _v(0) {}
template <class Self>
constexpr auto&& setV(this Self&& self, int v) {
self._v = v; return self;
}
private:
int _v;
};
Run Code Online (Sandbox Code Playgroud)
不幸的是,截至撰写本文时,唯一支持此功能的编译器是最新版本的 Microsoft Visual C++。
| 归档时间: |
|
| 查看次数: |
76 次 |
| 最近记录: |