问题标签 [overload-resolution]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - C++ 模板的问题(大惊喜!)。为什么这行不通?
我正在测试一种模仿 C# 属性的方法并创建了以下property
类:
我用以下代码测试了这个类:
这给了我一个意外的编译器错误,“ no match for 'operator='
...”,对于 line S = std::string(c);
。我注释掉了打印,S
因为我的operator=
问题似乎更简单,我希望它的解决方案也能解决operator<<
问题。为了弄清楚发生了什么,我手动实例化了模板,如下所示:
我的手动版本有效。谁能解释为什么模板版本没有?(我怀疑它与BY_REF
andBY_VAL
类有关,但我不知道为什么它适用于整数。)
delphi - 获取重载方法的地址位置
如何获取重载的函数/过程/方法的所有地址位置?
例如,Dialogs.MessageDlgPosHelp 有两个不同版本的重载 - 一个没有默认按钮,一个有默认按钮。如何获取这两个函数的地址位置?
c++ - Sun Studio 12 中的模板编译错误
我们正在迁移到 Sun Studio 12.1 和新的编译器 [CC: Sun C++ 5.10 SunOS_sparc 2009/06/03]。我在编译使用早期版本的 Sun 编译器 [CC: Sun WorkShop 6 update 2 C++ 5.3 2001/05/15] 编译良好的代码时遇到编译错误。
这是我得到的编译错误。
“Sample.cc”:错误:找不到 main() 中所需的 LoopThrough(int[2]) 的匹配项。1 检测到错误。*** 错误代码 1。
代码:
如果我用通用版本取消注释代码,代码编译得很好并且通用版本被调用。在禁用扩展的 MSVC 2010 和这里的 ideone 情况下,我没有看到这个问题。调用该函数的专用版本。现在的问题是,这是 Sun Compiler 中的错误吗?
如果是,我们如何提交错误报告?
c++ - 运算符重载解析如何在命名空间中工作?
我发现 C++ 解析运算符重载的奇怪行为,我无法解释自己。指向一些描述它的资源的指针与答案一样好。
我有 2 个翻译单元。在一个(称为 util.cpp/h)中,我声明并定义了两个运算符(为了可读性,我省略了真正的实现,无论如何都会出现问题):
和:
这些运算符当然是在全局命名空间中,因为它们对标准类型和内置类型进行操作,并且应该可以在任何地方使用。它们可以从全局命名空间(例如从 main())或显式告诉编译器它们在全局命名空间中正常工作(参见代码示例)。
在另一个翻译单元(称为 test.cpp/h)中,我在命名空间中使用这些运算符。这一直有效,直到我将类似的运算符放入此命名空间。一旦添加了此运算符,编译器(例如 gcc 或 clang)就无法再找到可行的运算符>>。
和:
为什么在命名空间中没有运算符>>时编译器会找到正确的运算符,但当有一个时却找不到?为什么即使它具有不同的签名,运算符也会影响编译器找到正确的能力?
解决此问题的一种尝试是
std::istream& operator>>(std::istream& is, const char* str) { ::operator>>(is, str); }
进入命名空间,但链接器抱怨以前的定义。所以附加:为什么链接器可以找到编译器找不到的东西?
c# - 在运行时解析成员名称
给定一个类型、一个名称和一个签名,我如何使用 7.4 的 C# 规则(或至少部分的 C# 语言规范中的章节号)对具有名称名称和签名签名的成员进行成员查找其中...假设我可以在运行时接受完全匹配,无需转换/转换) ?我需要得到一个MethodInfo
/ PropertyInfo
/... 因为然后我必须将它与反射一起使用(更准确地说,我正在尝试构建一个Expression.ForEach
构建器(一个能够创建表示foreach
语句的表达式树的工厂),并且是像素完美的 C#foreach
我必须能够进行鸭式打字并搜索GetEnumerator
方法(在集合中),Current
属性和MoveNext
方法(在枚举器中),如 8.8.4 中所写)
问题(问题的一个例子)
显然,如果我尝试typeof(C3).GetProperty("Current")
我会得到一个AmbiguousMatchException
例外。
接口存在类似但不同的问题:
在这里,如果我尝试做 atypeof(I3).GetProperties()
我没有得到Current
属性(这是已知的,例如参见GetProperties() 以返回接口继承层次结构的所有属性),但我不能简单地展平接口,因为那时我不知道谁在隐瞒谁。
我知道这个问题可能在Microsoft.CSharp.RuntimeBinder
命名空间中的某个地方得到了解决(在程序集中声明Microsoft.CSharp
)。这是因为我正在尝试使用 C# 规则,并且当您进行动态方法调用时,成员查找是必要的,但我无法找到任何东西(然后我会得到一个Expression
或可能是直接调用)。
经过一番思考,很明显Microsoft.VisualBasic
组件中有类似的东西。VB.NET 支持后期绑定。它在 中Microsoft.VisualBasic.CompilerServices.NewLateBinding
,但它没有公开后期的有界方法。
c++ - 为什么函数参数中的 const 限定符用于重载解析?
可能重复:
带有 const 参数和重载的函数
我对重载和 const 声明规则感到很困惑。这里有两件事让我感到困惑,也许你可以帮助我找到我脑海中更深层次的误解,导致他们对我感到困惑。;)
首要问题:
我的编译器允许这样做:
但是以下会导致编译错误(函数已经有一个主体):
我认为这是有道理的,因为我认为 const 只是在那里告诉编译器正在传递的对象没有改变,而在第二种情况下它无论如何都会被复制。但如果这是正确的,那么为什么我可以使用 const 重载函数?
换句话说,为什么如果我使用编译版本并调用这样的函数:
我得到“plain f”和“const f”而不是“const f”两次?显然现在我也使用 const 来告诉编译器调用哪个函数,不仅引用不会改变。这变得更加令人困惑,因为如果我删除“普通”版本,它就可以正常工作并两次调用“const”版本。
现在我的实际问题是什么?我想知道这种行为背后的想法是什么,因为否则很难记住它。
c# - 方法重载解析如何工作(LINQ Where 扩展方法)?
如果我有一个类型的变量,我有四个可用的命名空间IQueryable<T>
扩展方法:Where
Systm.Linq
(最后两个因为IQueryable<T>
继承自IEnumerable<T>
。)
如果我使用类型的变量ObjectQuery<T>
(在 namespace 中System.Data.Objects
),我有五个Where
可用的重载,即上面的四个(因为ObjectQuery<T>
实现IQueryable<T>
和IEnumerable<T>
其他接口)以及这个类的实例方法:
如果我在使用其中一个时犯了同样的编程错误,IQueryable<T>
或者ObjectQuery<T>
我得到了非常不同的编译器错误。这是一个示例程序(VS2010 SP1中的标准C#控制台应用程序模板+System.Data.Entity.dll
程序集添加到项目引用中,编译器错误在四个示例下面的注释中):
“Squiggles”在编译器中看起来也不同:
我理解前两个错误。但是为什么编译器显然想Func<T, int, bool> predicate
在最后两个示例中使用重载号 4(带有 )并且没有告诉我“名称”没有在类中定义Test
并且“bla”和“blabla”不存在在当前情况下?
我曾期望编译器可以安全地排除重载号 5(我不传入 a string
as 参数)和重载号 2 和 4(我不传入带有两个参数的 lambda 表达式(t,i) => ...
),但我的期望没有似乎是正确的。
作为旁注:我在查看这个问题时遇到了这个问题。提问者在那里说问题中的第四个查询无法编译(它在上面的示例 3 和 4 中完全有编译器错误),但是这个查询正是他的问题的解决方案,对我来说似乎有些东西(一个变量或属性名称?)在查询中写错了(虽然他没有确认这一点)但是这个编译器错误并没有给出有用的指示什么是错误的。
编辑
参考下面马丁哈里斯的非常有用的评论:
例如,当我将鼠标悬停在曲线上时query4
,错误“ Delegate System.Func does not take 1 argument ”是工具提示窗口中显示的错误。在编译器输出窗口中实际上按此顺序有四个错误:
- 委托 System.Func 不接受 1 个参数
- “lambda 表达式”无法转换为“字符串”,因为“字符串”不是委托类型
- 当前上下文中不存在名称“bla”
- 当前上下文中不存在名称“blabla”
但是为什么编译器不抱怨前两个使用的示例的第一个错误IQueryable<T>
?
c++ - 为什么这些重载的函数调用模棱两可?
为什么以下重载函数调用不明确?随着编译错误:
重载 'test(long int)' 的调用不明确,候选者是:void test(A)| 无效测试(B)|
编码:
c# - 具有不明确的返回类型和重载解决方案的 Lambda 转换
如果我有一个 lambda () => { throw new Exception(); }
,则不清楚它是否有返回类型。因此,它可以(隐式)转换为Action
and Func<object>
(或任何其他Func<T>
)。这是因为,根据C# 4 规范的§6.5匿名函数转换:
[A] 委托类型
D
与提供的匿名函数兼容F
:
…</p>
如果
D
有一个void
返回类型并且主体F
是一个语句块,当 [...] 主体F
是一个有效的语句块,其中没有返回语句指定一个表达式。如果
D
具有非 void 返回类型并且主体F
是语句块,则当 [...] 主体F
是具有不可到达终点的有效语句块时,其中每个return
语句都指定一个可隐式转换为返回的表达式的类型D
。
但是,如果我有一个方法的两个重载,其中一个有一个类型的参数,另一个有一个类型的参数Action
,Func<object>
并且我从上面将 lambda 传递给它,Func<object>
则使用重载。为什么?规范的哪一部分说这Func<object>
比Action
这种情况更好?
我看过 §7.5.3.2 Better function member,但这并没有解释它。
c++ - GCC 和 clang (SFINAE) 之间的重载解析行为差异
GCC 接受以下代码:
但是 clang 拒绝它并出现以下错误:
这似乎表明 GCC 和 clang 在重载解析期间执行某些操作的顺序有所不同。S
由于第二个参数 ( vs. int
)中的类型不匹配,GCC 似乎在尝试实例化候选模板的返回类型之前丢弃了候选模板,而 clang 似乎以相反的方式进行。
谁是对的?
我相信这个问题对模板库的作者有重要意义。具体来说,如果 clang 是正确的,那么模板的作者foo
将不得不做额外的工作来将错误转化为替换失败。
编辑:请注意,GCC和clang都拒绝了以下稍微简单的示例,并出现类似的错误:
暗示 GCC 知道“只有在函数类型及其模板参数类型的直接上下文中的无效类型和表达式才会导致推导失败”。此示例与原始示例之间的区别在于原始示例中存在第二个函数参数,基于此,GCC 在尝试对返回类型执行替换之前就抛出了候选模板。我认为问题是,GCC 按该顺序执行操作是否正确,或者它是否应该在考虑参数类型匹配之前尝试对返回类型执行替换。
更新: Luc Danton 的回答让我相信 clang 拒绝代码是正确的。我相应地提交了一个 GCC 错误。