可以采取哪些措施来防止对返回值进行误导性分配?

2023-12-14

使用 C++ 多年后,我意识到使用自定义类时语法中的一个怪癖。 尽管是正确的语言行为它允许创建非常具有误导性的界面。

这里的例子:

class complex_arg {
    double r_;
    double phi_;
 public:
    std::complex<double> value() const {return r_*exp(phi_*std::complex<double>{0, 1});}
};

int main() {
    complex_arg ca;
    ca.value() = std::complex<double>(1000., 0.);  // accepted by the compiler !?
    assert( ca.value() != std::complex<double>(1000., 0.) ); // what !?
}

https://godbolt.org/z/Y5Pcjsc8d

可以对类定义做什么来防止这种行为?(或者至少标记该类的用户第三行并没有真正执行任何作业。)

我只看到一种出路,但它需要修改类,并且它不能很好地扩展(对于可以移动的大型类)。

    const std::complex<double> value() const;

我也尝试过[[nodiscard]] value()但这没有帮助。

作为最后的手段,也许可以对返回的类型做一些事情std::complex<double> ?(也就是说,假设一个人控制着该班级)


请注意,我知道有时可能需要(优化)分配给新获得的值并将其传递给另一个函数f( ca.value() = bla )。我并不是质疑这种用法本身(尽管它也很令人困惑);我的问题主要是ca.value() = bla;作为一个独立的声明,它的作用并不像看上去的那样。


通常,我们可以调用对象的成员函数,无论该对象的值类别是左值还是右值。

可以对类定义做什么来防止这种行为?

在现代 C++ 之前,没有办法阻止这种用法。但从 C++11 开始,我们可以引用限定成员函数来执行您要求的操作,如下所示。

From 成员函数:

在过载解决期间,具有类的 cv 限定符序列的非静态成员函数X处理如下:

  • 无引用限定符:隐式对象参数具有对 cv 限定的左值引用类型X并且还允许绑定右值隐含对象参数

  • 左值引用限定符:隐式对象参数具有对 cv 限定的左值引用类型X

  • 右值引用限定符:隐式对象参数的类型为对 cv 限定 X 的右值引用


这使我们能够满足您对自定义托管类的要求。特别是,我们可以&限定复制赋值运算符。

struct C
{
    C(int)
    {
      std::cout<<"converting ctor called"<<std::endl;
    }
    C(){
        std::cout<<"default ctor called"<<std::endl;
    }
    C(const C&)
    {
     std::cout<<"copy ctor called"<<std::endl;
    }
//-------------------------v------>added this ref-qualifier
    C& operator=(const C&) &
    {
    std::cout<<"copy assignment operator called"<<std::endl;;
    return *this;
    }

};
C func()
{
    C temp;
    return temp;
}

int main()
{
//---------v---------> won't work because assignment operator is & qualified
    func() = 4;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

可以采取哪些措施来防止对返回值进行误导性分配? 的相关文章

随机推荐

  • 禁用 CURLOPT_SSL_VERIFYPEER (libcurl/openssl) 的安全后果

    我知道从这个线程禁用 CURLOPT SSL VERIFYHOST 时可能发生哪些攻击 我想知道禁用 VERIFYPEER 而不是 VERIFYHOST 时可能发生哪些攻击 使用信用卡付款的风险是否可以接受 我问的原因是因为我的code仅适
  • Pygame 蛇食物生成器

    我目前正在创建一个贪吃蛇游戏 我想创建一个食物生成器 根据我的游戏计时器每 10 秒生成一个苹果 计时器从 60 倒数到 0 游戏结束时 我希望每 10 秒生成一个新苹果 保留旧苹果 即使它还没有被吃掉 我不知道如何解决这个问题 需要一些帮
  • Windows Visual Studio 2008 中的 Unix Makefile

    我已经进行了不错的搜索 但似乎找不到一种方法让 Visual Studio 2008 使用 unix Makefile 甚至无法从 Makefile 创建一些与 MSVC 兼容的等效文件 有人有想法或类似的问题吗 注意 我已经知道使用 Ma
  • 在 macOS Big Sur 上将 Python 3.7 升级到 3.9

    我正在尝试在 macOS Big Sur 上将 Python 3 7 升级到 3 9 我还试图避免丢失在 Python 3 7 上安装的包并在 Python 3 9 上再次重新安装它们 我尝试使用 brew install python3
  • 是否可以仅使用 C# 以编程方式生成 X509 证书?

    我们正在尝试使用 C 和以下代码以编程方式生成 X509 证书 包括私钥 充气城堡图书馆 我们尝试使用一些代码这个样本由 Felix Kollmann 制作但证书的私钥部分返回 null 代码及单元测试如下 using System usi
  • 在 R 中拟合 Log Pearson III 时出现问题

    我想对我拥有的一些数据点执行对数 Pearson III 拟合 然而 每次我尝试这样做时 我都会收到错误消息 我真的不知道该怎么办 也许我应该补充一点 我从几天前才开始使用 R 所以 我不是这方面的专家 重要的代码部分 没有导入内容的部分等
  • 合并两个字典同时共享密钥

    我正在尝试构建一个小程序 给定一个包含姓名和地址的字典和另一个包含姓名和电话号码的字典 输出应该将它们合并 并且不会相互覆盖 最终输出字典应包含姓名 地址 如果可用 和电话 如果可用 这是一个例子 addr George via Wagne
  • 如何复制当前活动的浏览器 URL?

    我正在尝试获取活动浏览器窗口的当前活动浏览器 URL 有任何指针或代码示例吗 Code NSAppleScript script NSAppleScript alloc initWithSource tell application Saf
  • 调试无法检查变量

    while debugging in eclipse the problem is String hashCode line 1489 local variables unavailable thus not able to inspect
  • Android 网络服务 GPS 导航

    如何在应用程序导航中显示以查找方向和搜索任何地方 当我们在浏览器中打开谷歌地图时会发生这种情况 但我希望在应用程序中也有同样的情况 None
  • 获取已安装 COM 对象的 GUID

    我有一个 32 位 COM 对象 我想将其与 64 位 PHP 一起使用 我正在尝试按照这里的教程进行操作 http www gfi com blog 32bit object 64bit environment 但我被困在 找到你的 CO
  • ASP.NET Excel导出编码问题

    我正在 ASP NET 网站上进行一些 Excel 导出 除了编码之外 一切正常 当我在 Excel 中打开它时 它看起来像这样 Eingabe Kosten je Ger t Ger t 特殊情况 Betriebsmittel Heiz
  • Bootstrap:更改移动设备上全角列的顺序

    我有这样的架构 col 1 col 2 它们的宽度都是12块 和我的html div class col xs 12 col md 5 1 div div class col xs 12 col md 7 2 div 是否可以在 xs mo
  • 从 VTCompressionOutputCallback 中引用“self”[重复]

    这个问题在这里已经有答案了 我目前正在尝试使用 VideoToolbox 对来自AVCaptureVideoDataOutput 但我在引用时遇到问题self从内部VTCompressionOutputCallback 我的代码如下 var
  • 线程和 GUI 应用程序之间的 Python 新型信号和插槽

    我是 OOP 和 python 的新手 我正在尝试使用新样式的信号和插槽从 Qthread 向 Qt GUI 主窗口发出信号 这就是线程 在单击 GUI 中的 运行 按钮后 3 秒后 我将在 GUI 中发出用于更新消息对话框的信号 我不确定
  • 在Python中序列化二进制数据

    我有一些二进制数据 在 Python 中以字节字符串数组的形式存在 是否有一种可移植的方法来序列化其他语言可以读取的数据 JSON 失败是因为我刚刚发现它没有真正的方法来存储二进制数据 它的字符串应该是 Unicode 我不想使用pickl
  • 在浏览器中执行jdbc小程序

    import java sql import java io import java awt import java awt event import java applet public class A0 extends Applet i
  • 使用连字符时 Spring 表达式语言 (SpEL) 不起作用

    我正在尝试使用 Spring 表达式语言来解析表达式 if myVariable值设置为 first name 带连字符的值 然后获取class org springframework expression spel SpelParseEx
  • 使用 Java 将 ASN1 序列解码为 RSA 公钥

    我有以下 RSA 公钥作为 ASN1 序列 SEQUENCE 2 elem INTEGER 1024 bit 14832 INTEGER 65537 如何在 Java 中将此序列导入为 RSA 公钥 已实施的KeySpecs 例如PKCS8
  • 可以采取哪些措施来防止对返回值进行误导性分配?

    使用 C 多年后 我意识到使用自定义类时语法中的一个怪癖 尽管是正确的语言行为它允许创建非常具有误导性的界面 这里的例子 class complex arg double r double phi public std complex