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

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(使用前将#替换为@)

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

  • 使用 std::packaged_task/std::exception_ptr 时,线程清理程序报告数据争用

    我遇到了线程清理程序 TSan 的一些问题 抱怨某些生产代码中的数据争用 其中 std packaged task 通过将它们包装在 std function 中而移交给调度程序线程 对于这个问题 我简化了它在生产中的作用 同时触发 TSa
  • MVC 在布局代码之前执行视图代码并破坏我的脚本顺序

    我正在尝试将所有 javascript 包含内容移至页面底部 我正在将 MVC 与 Razor 一起使用 我编写了一个辅助方法来注册脚本 它按注册顺序保留脚本 并排除重复的内容 Html RegisterScript scripts som
  • 在 LINQ 中按 Id 连接多表和分组

    我想按categoryId显示列表产品的名称组 这是我的代码 我想要我的视图显示结果 Desktop PC HP Red PC Dell Yellow PC Asus Red SmartPhone Lumia 720 Blue 我的组模型
  • 错误:表达式不产生值

    我尝试将以下 C 代码转换为 VB NET 但在编译代码时出现 表达式不产生值 错误 C Code return Fluently Configure Mappings m gt m FluentMappings AddFromAssemb
  • 当我们想要返回对象的引用时,为什么我们在赋值运算符中返回 *this 而通常(而不是 this)?

    我正在学习 C 和指针 我以为我理解了指针 直到我看到这个 一方面 asterix 运算符是解引用的 这意味着它返回值所指向的地址中的值 而与号 运算符则相反 它返回值存储的地址记忆 现在阅读有关赋值重载的内 容 它说 我们返回 this因
  • 单个对象的 Monogame XNA 变换矩阵?

    我读过一些解释 XNA Monogame 变换矩阵的教程 问题是这些矩阵应用于 SpriteBatch Begin matrix 这意味着所有 Draw 代码都将被转换 如何将变换矩阵应用于单个可绘制对象 就我而言 我想转换滚动背景 使其自
  • 使用接口有什么好处?

    使用接口有什么用 我听说它用来代替多重继承 并且还可以用它来完成数据隐藏 还有其他优点吗 哪些地方使用了接口 程序员如何识别需要该接口 有什么区别explicit interface implementation and implicit
  • 如何使用 LINQ2SQL 连接两个不同上下文的表?

    我的应用程序中有 2 个数据上下文 不同的数据库 并且需要能够通过上下文 B 中的表的右连接来查询上下文 A 中的表 我该如何在 LINQ2SQL 中执行此操作 Why 我们正在使用 SaaS 产品来跟踪我们的时间 项目等 并希望向该产品发
  • 由 IHttpClientFactory 注入时模拟 HttpClient 处理程序

    我创建了一个自定义库 它会自动为依赖于特定服务的 Polly 策略设置HttpClient 这是使用以下方法完成的IServiceCollection扩展方法和类型化客户端方法 一个简化的例子 public static IHttpClie
  • 在 C 中初始化变量

    我知道有时如果你不初始化int 如果打印整数 您将得到一个随机数 但将所有内容初始化为零似乎有点愚蠢 我问这个问题是因为我正在评论我的 C 项目 而且我对缩进非常直接 并且它可以完全编译 90 90 谢谢 Stackoverflow 但我想
  • C# 中的合并运算符?

    我想我记得看到过类似的东西 三元运算符 http msdn microsoft com en us library ty67wk28 28VS 80 29 aspx在 C 中 它只有两部分 如果变量值不为空 则返回变量值 如果为空 则返回默
  • 如何设置 log4net 每天将我的文件记录到不同的文件夹中?

    我想将每天的所有日志保存在名为 YYYYMMdd 的文件夹中 log4net 应该根据系统日期时间处理创建新文件夹 我如何设置它 我想将一天中的所有日志保存到 n 个 1MB 的文件中 我不想重写旧文件 但想真正拥有一天中的所有日志 我该如
  • 将 MQTTNet 服务器与 MQTT.js 客户端结合使用

    我已经启动了一个 MQTT 服务器 就像this https github com chkr1011 MQTTnet tree master例子 该代码托管在 ASP Net Core 2 0 应用程序中 但我尝试过控制台应用程序 但没有成
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装
  • System.IO.FileNotFoundException:找不到网络路径。在 Windows 7 上使用 DirectoryEntry 对象时出现异常

    我正在尝试使用 DirectoryEntry 对象连接到远程 Windows 7 计算机 这是我的代码 DirectoryEntry obDirEntry new DirectoryEntry WinNT hostName hostName
  • C++ 条件编译

    我有以下代码片段 ifdef DO LOG define log p record p else define log p endif void record char data 现在如果我打电话log hello world 在我的代码中
  • 使用 .NET Process.Start 运行时挂起进程 - 出了什么问题?

    我在 svn exe 周围编写了一个快速而肮脏的包装器来检索一些内容并对其执行某些操作 但对于某些输入 它偶尔会重复挂起并且无法完成 例如 一个调用是 svn list svn list http myserver 84 svn Docum
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看
  • 当从finally中抛出异常时,Catch块不会被评估

    出现这个问题的原因是之前在 NET 4 0 中运行的代码在 NET 4 5 中因未处理的异常而失败 部分原因是 try finallys 如果您想了解详细信息 请阅读更多内容微软连接 https connect microsoft com
  • 如何将 PostgreSql 与 EntityFramework 6.0.2 集成? [复制]

    这个问题在这里已经有答案了 我收到以下错误 实体框架提供程序类型的 实例 成员 Npgsql NpgsqlServices Npgsql 版本 2 0 14 2 文化 中性 PublicKeyToken 5d8b90d52f46fda7 没

随机推荐

  • 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