问题标签 [ambiguous-call]

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.

0 投票
1 回答
68 浏览

c++ - 避免在人为的模棱两可的重载函数调用中拼写出类型

最小示例程序:

直觉上,这是一个有效的程序是有意义的:使用重载#1 的调用将是有效的,使用重载#2 的调用将是格式错误的,因此应该选择重载#1。这就是 clang 所做的。

不幸的是,按照标准,这似乎是模棱两可的,因为有一个构造函数std::vector<void *>可以用 调用int,通过隐式将其转换为size_texplicit在重载决议期间应该忽略该构造函数的事实,如果选择该重载,程序将只是格式错误。GCC 以模棱两可的方式拒绝该呼叫,并且这样做看起来是正确的。

我可以修改代码,让 GCC 通过拼写类型名称来接受调用:f(std::vector<int>{ 1 });。我也可以使用带有默认参数的标签调度来明确指定要使用的重载,同时允许像以前一样接受现有调用。

这两个都是可以接受的,但是当回到真实代码时会很快变得相当冗长。是否有另一个选项可以让我避免拼出完整的类型名称,但坚持使用当前的重载?我想了一会儿{ 1, }可能会起作用,但当然它不会,int i = { 1, };也是完全有效的,不能用来避免#2。

如果有助于排除某些替代方案,则实际代码确实涉及std::vector<int>并且std::vector<T>确实涉及使用包含单个整数表达式的花括号初始化列表的调用,但T它是用户定义的类型,而不是内置类型,并且表达式是不是一个常数值。

“否”是可以接受的答案,但在这种情况下,请详细说明,请表明没有这样的选项。

0 投票
3 回答
383 浏览

c++ - 朋友和成员二元运算符的消歧

考虑以下带有二元运算符的类(我operator+仅用作示例)。

我可以用两种不同的类型调用这个二元运算符:

然后,当我尝试A在两边都使用 ( a + a) 时,会发生很多奇怪的事情。三个编译器对相同的代码给出不同的答案。

一些上下文:我不想定义void operator+(A const&),因为如果某些语法不起作用,我需要一个模板来 SFINAE 函数。我也不想要一个template<class BB, class AA> friend void operator(BB const&, AA const&). 因为sinceA是一个模板,不同的实例化会产生同一个模板的多个定义。

继续原始代码:

奇怪的事情#1:在gcc中,朋友优先:

我希望会员优先,有没有办法让会员优先gcc?

奇怪的事情#2:在clang中,这段代码无法编译:

这已经指出了 gcc 和 clang 之间的不一致,谁是对的? 让clang像gcc一样工作的解决方法是什么?

如果我尝试在参数中更加贪婪,例如应用一些优化,我可以使用转发引用:

奇怪的事情#3:使用转发引用会在 gcc 中发出警告,

但仍然可以编译,如何在 gcc 或解决方法中消除此警告?就像案例 #1 一样,我希望更喜欢成员函数,但在这里它更喜欢朋友函数给出警告。

奇怪的事情#4:使用转发引用会在clang中出错。

这再次指出 gcc 和 clang 之间的不一致,在这种情况下谁是对的?

总之,我试图让这段代码始终如一地工作。我真的希望该功能被注入朋友功能(不是免费的朋友功能)。我不想定义具有相同非模板参数的函数,因为不同的实例化会产生相同函数的重复声明。


这是完整的代码:


注意:我正在使用clang version 6.0.1and g++ (GCC) 8.1.1 20180712。根据 Francis Cugler 的说法,MSVS 2017 CE 给出了不同的行为。


我找到了一种解决方法,可以为 clang 和 gcc(对于 MSVS?)执行正确的操作(为 case 打印 'member' a+a),但是对于样板和人工基类需要很多:

但是,如果我替换BB const&BB&&.

0 投票
3 回答
187 浏览

c++ - 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?

我想使用std::sort,但编译失败并出现错误C2668: std::swap: ambiguous call to overloaded function,因为swap()在我的命名空间中定义了一个很难删除的模板化函数。我不在乎swap它使用哪个,但是在编译时如何使它们中的任何一个消失sort()

我知道这是模棱两可的,因为my::swap它与 位于相同的命名空间中my::Obj,而且我不在乎swap使用哪个版本。我只需要克服命名空间冲突。这是我不拥有的一个非常大的代码库的一部分,所以我希望有一个解决方案是我的代码本地的,并且可能允许my::Obj并且my::swap都保留在 namespace 中my

0 投票
1 回答
120 浏览

c# - 参数中通用字符串和简单字符串之间的歧义

我有 2 种方法,其中一种适用于通用参数,另一种适用于常规字符串。它看起来像这样:

我想知道,为什么调用编译下一个调用结果时出现歧义错误?String在这种情况下显然没有实现IAlertSource

有任何想法吗?谢谢。

0 投票
2 回答
36 浏览

c++ - 如何重载就地和复制字符串操作函数?

我希望能够做到以下几点:

为此,我有两个功能

但它们会产生以下错误:

我该如何克服呢?

0 投票
1 回答
829 浏览

c++ - 如何解决采用 std::string 和 std::vector 的构造函数之间的歧义

我想创建一个“标签”类,它的名称可以指定为点分隔名称,也可以指定为"this.is.my.name"字符串向量,例如{"this","is","my","name"}.

当我尝试这样做时,有时编译器会告诉我我的调用是模棱两可的。我想知道(1)为什么这是模棱两可的,以及(2)为什么有时只是模棱两可。

这是我的示例代码,您也可以在 Coliru 上查看和编译

使用指示的行,我收到以下错误:

0 投票
1 回答
142 浏览

c++ - 以 nullptr 作为参数的函数重载解析

考虑下面的代码。fun尽管接受指针的两个重载,传递nullptrfun都不会导致任何编译错误。然而,非常相似的函数bun无法编译。当我i使用打印参数的类型时typeid(i).name() (在修改代码只是为了打印它之后)我得到相同的类型,只是int*. 在 case 中解决歧义fun但失败的规则是什么bun?提前致谢!

0 投票
2 回答
89 浏览

c++ - 模棱两可的重载函数仅因参数的模板形参不同

考虑以下代码:

我将如何重写它以使其不会导致“错误 C2668:对重载函数的模糊调用”?

注意:例如,我也希望能够传入一个子类SmartPointer<SubclassOfDataWrapper>,并将其解析为超类的重载函数。

0 投票
1 回答
433 浏览

c++11 - 无法理解(并修复)为什么存在此警告“重载 xxx 的调用不明确”

我一直在修复这个 gcc 警告:我得到了方法“registerCalBack”的树版本,它们每个都采用通过 std::function 引入的不同“可调用”。根据我声明的各种可调用类型,我可以编译或不编译,gcc 发出警告“重载 registerCallBackxxxxx 的调用不明确”。

我知道编译器可以通过考虑参数而不是返回类型来解决重载,但在这种情况下,我无法理解为什么 gcc 会出现歧义:对我来说,每个 TCallBack ... 我定义的参数都不同,当我改变时第三个的返回类型,它编译......这真的让我很困惑。我想问题的一部分来自于一些参数实际上是不完整类型的事实,但这是从 SDL 标头访问它们的方式,所以我复制了我在这个线程中提供的示例。

在代码中的注释中,您获得了已编译的定义示例和其他未编译的定义示例。

我希望你们中的一些人会比我更好地理解,现在我不知道在哪里看。提前谢谢了。

这里要编译的 gcc 命令行:

P。

0 投票
2 回答
126 浏览

c++ - 带有可变参数包的函数的 C++ 部分模板参数推导在 Clang 和 MSVC 中产生模棱两可的调用

考虑以下代码片段(可在编译器 epxlorer上获得):

它对于 GCC 编译得非常好,对于 Clang 和 MSVC 都失败了(编译器说ambiguous call

为什么 Clang 和 MSVC 无法进行如此看似明显的推论?

编辑:GCC 为我作为用户提供了预期的解决方案,是否有一种简单的方法可以推动 clang 和 msvc 选择模板而无需对原始代码进行太多更改?