类内友元运算符似乎不参与重载决策

2023-12-02

在编写允许类提供重载的 CRTP 模板时operator+基于模板参数,我发现如果类内友元运算符的参数都不属于它定义的类的类型,则该运算符似乎不会参与重载决策。

煮沸:

enum class FooValueT{
    zero, one, two
};

class Foo{
    FooValueT val_;
public:
    Foo(FooValueT x) : val_(x){};

    Foo& operator+=(Foo other){
        val_ = (FooValueT)((int)val_ + (int)other.val_);
        return *this;
    }

    //overload for Foo+Foo, FooValueT+Foo and Foo+FooValueT
    friend Foo operator+(Foo lhs, Foo rhs){
        Foo ret = lhs;
        return ret += lhs;
    }

    //explicit overload for FooValueT+FooValueT
    friend Foo operator+(FooValueT lhs, FooValueT rhs){
        return (Foo)lhs + (Foo)rhs;
    }
};

看起来有点多余,但是很有必要Foo my = FooValueT::one + FooValueT::zero;应该是一个有效的表达式,如果没有一个参数具有类类型,则它们不会隐式转换,如中所述这个答案我之前的一个问题。

尽管付出了所有这些努力,以下代码仍无法编译:

int main(int argc, char* argv[])
{
    Foo my = FooValueT::zero;
    my += FooValueT::one;
    my = Foo(FooValueT::zero) + FooValueT::two;
    my = FooValueT::zero + Foo(FooValueT::two);
    my = FooValueT::zero + FooValueT::two; //error C2676
    return 0;
}

错误信息是:

error C2676: binary '+' : 'FooValueT' does not define this operator or a conversion to a type acceptable to the predefined operator

一旦我将运算符完全移出类,或者将其声明为友元但将其定义在类之外,这个问题就解决了。两者似乎都不是可行的选择Foo是一个要派生的模板类。

据我所知,上面的课堂朋友定义operator+(ValueT,ValueT)应该创建一个自由函数,就像这个定义一样:

class Foo{
/*All the stuff you saw previously*/
    friend Foo operator+(FooValueT lhs, FooValueT rhs);
};

Foo operator+(FooValueT lhs, FooValueT rhs){
    return (Foo)lhs + (Foo)rhs;
}

我这里哪里出错了?与常规自由友元函数相比,函数的类内友元定义是否会改变重载解析规则?


n3376 11.3/6-7

函数可以在类的友元声明中定义,如果并且 仅当该类是非本地类(9.8)时,函数名称为 不合格,并且该函数具有命名空间范围。

这样的函数是隐式内联的。定义在 a 中的友元函数 class 位于定义它的类的(词法)范围内。 A 在类外部定义的友元函数不是(3.4.1)。

在您的情况下,运算符位于类范围内,并且当您尝试调用此运算符时,ADL 将不会尝试在类中查找运算符,因为两个参数都没有此类的类型。只需编写自由函数(或声明不在类中的朋友)。

似乎你不能做这样的事情,在类中声明友元函数的问题是该函数将在类范围内,但你不能将此函数声明为自由友元函数,因为编译器无法推断返回类型参数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

类内友元运算符似乎不参与重载决策 的相关文章

  • 使用链表进行堆排序

    我想知道是否有人曾经使用链表进行堆排序 如果他们可以提供代码 我已经能够使用数组进行堆排序 但尝试在链表中进行排序似乎不切实际 而且在你知道的地方很痛苦 我必须为我正在做的项目实现链接列表 任何帮助将不胜感激 我也用C 答案是 你不想在链表
  • 如何从字符串中提取子字符串直到遇到第二个空格?

    我有一个像这样的字符串 o1 1232 5467 1232 5467 1232 5467 1232 5467 1232 5467 1232 5467 如何仅提取 o1 1232 5467 要提取的字符数并不总是相同 因此 我只想提取直到遇到
  • 是否需要销毁运算符删除的形式才能真正销毁对象?

    C 20 添加了破坏形式operator delete区别于std destroying delete t范围 它导致delete表达式在调用之前不再销毁对象operator delete 目的是在显式调用对象的析构函数和释放内存之前 允许
  • 静态构造函数和 BeforeFieldInit?

    如果类型没有静态构造函数 则将执行字段初始值设定项 就在使用该类型之前 或者在某个时间点突发奇想 运行时 为什么这段代码 void Main start Dump Test EchoAndReturn Hello end Dump clas
  • 如何使用 openSSL 函数验证 PEM 证书的密钥长度

    如何验证以这种方式生成的 PEM 证书的密钥长度 openssl genrsa des3 out server key 1024 openssl req new key server key out server csr cp server
  • strlen() 编译时优化

    前几天我发现你可以找到编译时strlen使用这样的东西 template
  • 在 C++ 代码中转换字符串

    我正在学习 C 并开发一个项目来练习 但现在我想在代码中转换一个变量 字符串 就像这样 用户有一个包含 C 代码的文件 但我希望我的程序读取该文件并插入将其写入代码中 如下所示 include
  • 2个对象,完全相同(除了命名空间)c#

    我正在使用第三方的一组网络服务 但遇到了一个小障碍 在我手动创建将每个属性从源复制到目标的方法之前 我想我应该在这里寻求更好的解决方案 我有 2 个对象 一个是 Customer CustomerParty 类型 另一个是 Appointm
  • 使用 C# 和 ASP.NET 在电子邮件附件中发送 SQL 报告

    我正在尝试使用 ASP NET 和 C 从 sql reportserver 2008 作为电子邮件附件发送报告 到目前为止我学会了如何获取 PDF 格式的报告 http weblogs asp net srkirkland archive
  • 防止控制台应用程序中的内存工作集最小化?

    我想防止控制台应用程序中的内存工作集最小化 在Windows应用程序中 我可以这样做覆盖 SC MINIMIZE 消息 http support microsoft com kb 293215 en us fr 1 但是 如何在控制台应用程
  • JavaScript 错误:MVC2 视图中的条件编译已关闭

    我试图在 MVC2 视图页面中单击时调用 JavaScript 函数 a href Select a JavaScript 函数 function SelectBenefit id code alert id alert code 这里 b
  • LinkLabel 无下划线 - Compact Framework

    我正在使用 Microsoft Compact Framework 开发 Windows CE 应用程序 我必须使用 LinkLabel 它必须是白色且没有下划线 因此 在设计器中 我将字体颜色修改为白色 并在字体对话框中取消选中 下划线
  • 条件类型定义

    如果我有一小段这样的代码 template
  • 如何在 Javascript 中连接 C# ActiveX 事件处理程序

    我尝试使用几个代码片段将 ActiveX 对象与 Javascript 事件处理程序挂钩 我无法确定为什么事件处理程序没有被调用 带有项目的 Github 存储库 https github com JesseKPhillips Csharp
  • Unity c# 四元数:将 y 轴与 z 轴交换

    我需要旋转一个对象以相对于现实世界进行精确旋转 因此调用Input gyro attitude返回表示设备位置的四元数 另一方面 这迫使我根据这个四元数作为默认旋转来计算每个旋转 将某些对象设置为朝上的简单方法如下 Vector3 up I
  • 当Model和ViewModel一模一样的时候怎么办?

    我想知道什么是最佳实践 我被告知要始终创建 ViewModel 并且永远不要使用核心模型类将数据传递到视图 这就说得通了 让我把事情分开 但什么是Model 和ViewModel一模一样 我应该重新创建另一个类还是只是使用它 我觉得我应该重
  • Xamarin Forms Binding - 访问父属性

    我无法访问页面的 ViewModel 属性以便将其绑定到 IsVisible 属性 如果我不设置 BindingContext 我只能绑定它 有没有办法可以在设置 BindingContext 的同时访问页面的 viewmodel root
  • 如何编写一个接受 int 或 float 的 C 函数?

    我想用 C 语言创建一个扩展 Python 的函数 该函数可以接受 float 或 int 类型的输入 所以基本上 我想要f 5 and f 5 5 成为可接受的输入 我认为我不能使用if PyArg ParseTuple args i v
  • 如何组合两个 lambda [重复]

    这个问题在这里已经有答案了 可能的重复 在 C 中组合两个 lambda 表达式 https stackoverflow com questions 1717444 combining two lamba expressions in c
  • 如何在 C# 中获取 CMD/控制台编码

    我需要指定正确的代码页来使用 zip 库打包文件 正如我所见 我需要指定控制台编码 在我的例子中为 866 C Users User gt mode Status for device CON Lines 300 Columns 130 K

随机推荐

  • Symfony2 - Doctrine2:跨数据库连接列抛出映射异常

    您好 想要在两个实体之间建立连接 这些实体位于不同的数据库中 这是我设置数据库配置的方法 doctrine dbal default connection default connections default driver databas
  • 如何在 jQuery 悬停菜单上允许默认子菜单

    这要从一个相关问题 在得到一个出色的答案后 我遇到了一个不可预见的功能差距 如何显示默认打开的菜单 更具体地说 如果用户登陆我的子导航中存在的页面 我希望打开该子导航并突出显示当前页面 如果他们使用菜单浏览 菜单会相应更改 但如果他们不进行
  • 如何有效地仅读取文本文件的最后一行

    需要从大日志文件中获取最后一行 最好的方法是什么 您想使用向后读取文件ReverseLineReader 如何在C 中使用迭代器反向读取文本文件 然后运行 Take 1 on it var lines new ReverseLineRead
  • 将标注添加到 Highcharts - 堆叠栏

    我正在尝试使用来自的堆叠条形图制作年龄时间表高图表 我想要有多个指向时间线中数据点的调用 我本来打算使用工具提示 但我需要始终显示所有工具提示 并且每个工具提示需要不同的内容 所以我认为使用呼叫会是更好的解决方案 如何确保我的标注指向我需要
  • 无法使用 OpenSSL 的 ssl.SSLContext() 在 Python 客户端中接收对等证书

    我是 Windows 用户 我用Python 3 6 5我导入这个版本的 OpenSSLOpenSSL 1 0 2k 我需要为 python TLS 客户端编写一个脚本 我可以根据支持的 TLS 版本 密码套件和其他配置进行自定义 客户端应
  • 为什么节点 REPL 中未定义 __dirname?

    从节点手册中我看到我可以使用以下命令获取文件的目录 dirname 但从 REPL 来看 这似乎是未定义的 这是我的误解还是错误在哪里 node gt console log dirname ReferenceError dirname i
  • JavaScript 无法通过 Rails 中的引导模板运行

    我创建了一个新的 Rails 应用程序并安装了所有必要的 gem 添加了所有文件 更新了 application js 文件 一切正常 但由于某种原因 所有与 javascript 相关的东西都不起作用 我使用这个模板 https star
  • Discord.py:想要将 message.content 读为小写,.lower() 不起作用

    import discord import asyncio import sys from discord ext import commands client commands Bot command prefix id client g
  • 检测是否安装了从右到左的语言

    检测主机 Windows 操作系统上是否安装了从右到左语言的最简单方法是什么 我需要这个才能知道 LTR 标记是否会显示为正方形 或者在主机操作系统上是否正常工作 可能是非托管 API 例如是否有效语言组 有效区域设置名称 or 有效区域设
  • swift 中 UITableView 的动态数据源/委托

    我需要根据某些条件设置不同的对象作为表视图的数据源和委托 但我无法分配表视图的数据源 委托 因为它会引发一些错误 无法分配 NSObject 类型的值 为 UITableViewDelegate 类型的值 我确实检查过this问答但这没有用
  • Android:可打包和可序列化之间的区别?

    为什么Android提供2个接口用于序列化对象 可序列化对象是否与 Android 互操作Binder和 AIDL 文件 在 Android 中 我们不能只将对象传递给 Activity 为此 对象必须实现Serializable or P
  • 为什么静态类的成员需要声明为静态?为什么它不只是隐式的?

    显然 静态类上不能有实例成员 因为该类永远无法实例化 为什么我们需要将成员声明为静态 我总是被问到这样的问题 基本上 问题归结为 当编译器可以推断出有关已声明成员的事实时 该事实的显式声明应该是 1 必需的 2 可选的 还是 3 禁止的 没
  • 选择选项元素上的单击事件不起作用[关闭]

    Closed 这个问题需要细节或清晰度 目前不接受答案 我知道我必须改变id into a val但怎么办 任何想法 抱歉 这对你们来说可能很容易 但对我来说却不是 每个选项滚动到特定标签 但单击不起作用 http jsfiddle net
  • 动态更新 UILabel

    我有一个关于 UILabels 的问题 我什至不确定这是实现这一目标的正确方法 但我正在尝试更新 UILabel 以显示从 0 到 24 的两个数字 然后循环回零并再次显示数字序列 问题是 它需要每 1 24 秒更新一次 UILabel 这
  • NSException raise:format: 作为方法中的最后一个语句

    我有这个方法 MHTwitterParser createParser NSString format if format compare json NSOrderedSame return MHJsonTwitterParser allo
  • 如何对齐两个(或更多)图表的大小、滚动和网格

    我有三个涉及同一周期的信号 伏尔门 电流和能量 我在两张图表上打印数据 一张显示电压 蓝色 和电流 红色 另一张仅显示能量 橙色 它们是两个不同的图表 但实际上 它们共享相同的 X 轴 我有两个与鼠标移动同步的光标 充当两个图形的一个光标
  • 使用闪亮的动态CheckboxGroupInput

    我正在尝试创建一个复选框 以便能够按年份过滤数据集 然而 并非每个变量都具有每年的所有数据 因此我只想要变量具有用户界面中显示的数据的年份 遗憾的是 将我的代码拆分为条件面板后 按钮不再进行过滤 conditionalPanel condi
  • 如何使用 ui-router 将对象从 1 $state 发送到另一个 $state

    https plnkr co edit nqyBTcBgBimjkrpf2oYo p preview Expected After Login Selecting a Ticker button should make the Tags m
  • 如果元标记出现在文档正文中会发生什么?

    我正在开发一个 ASP 应用程序 代码 模板和文件的组织方式不允许我更改 body 标记之外的任何内容 所以我正在考虑在正文中插入元标记 像这样 div class dynamic content div
  • 类内友元运算符似乎不参与重载决策

    在编写允许类提供重载的 CRTP 模板时operator 基于模板参数 我发现如果类内友元运算符的参数都不属于它定义的类的类型 则该运算符似乎不会参与重载决策 煮沸 enum class FooValueT zero one two cla