问题标签 [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.
c++ - 避免在人为的模棱两可的重载函数调用中拼写出类型
最小示例程序:
直觉上,这是一个有效的程序是有意义的:使用重载#1 的调用将是有效的,使用重载#2 的调用将是格式错误的,因此应该选择重载#1。这就是 clang 所做的。
不幸的是,按照标准,这似乎是模棱两可的,因为有一个构造函数std::vector<void *>
可以用 调用int
,通过隐式将其转换为size_t
。explicit
在重载决议期间应该忽略该构造函数的事实,如果选择该重载,程序将只是格式错误。GCC 以模棱两可的方式拒绝该呼叫,并且这样做看起来是正确的。
我可以修改代码,让 GCC 通过拼写类型名称来接受调用:f(std::vector<int>{ 1 });
。我也可以使用带有默认参数的标签调度来明确指定要使用的重载,同时允许像以前一样接受现有调用。
这两个都是可以接受的,但是当回到真实代码时会很快变得相当冗长。是否有另一个选项可以让我避免拼出完整的类型名称,但坚持使用当前的重载?我想了一会儿{ 1, }
可能会起作用,但当然它不会,int i = { 1, };
也是完全有效的,不能用来避免#2。
如果有助于排除某些替代方案,则实际代码确实涉及std::vector<int>
并且std::vector<T>
确实涉及使用包含单个整数表达式的花括号初始化列表的调用,但T
它是用户定义的类型,而不是内置类型,并且表达式是不是一个常数值。
“否”是可以接受的答案,但在这种情况下,请详细说明,请表明没有这样的选项。
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.1
and g++ (GCC) 8.1.1 20180712
。根据 Francis Cugler 的说法,MSVS 2017 CE 给出了不同的行为。
我找到了一种解决方法,可以为 clang 和 gcc(对于 MSVS?)执行正确的操作(为 case 打印 'member' a+a
),但是对于样板和人工基类需要很多:
但是,如果我替换BB const&
为BB&&
.
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
。
c# - 参数中通用字符串和简单字符串之间的歧义
我有 2 种方法,其中一种适用于通用参数,另一种适用于常规字符串。它看起来像这样:
我想知道,为什么调用编译下一个调用结果时出现歧义错误?String
在这种情况下显然没有实现IAlertSource
有任何想法吗?谢谢。
c++ - 如何重载就地和复制字符串操作函数?
我希望能够做到以下几点:
也
为此,我有两个功能
但它们会产生以下错误:
我该如何克服呢?
c++ - 如何解决采用 std::string 和 std::vector 的构造函数之间的歧义
我想创建一个“标签”类,它的名称可以指定为点分隔名称,也可以指定为"this.is.my.name"
字符串向量,例如{"this","is","my","name"}
.
当我尝试这样做时,有时编译器会告诉我我的调用是模棱两可的。我想知道(1)为什么这是模棱两可的,以及(2)为什么有时只是模棱两可。
这是我的示例代码,您也可以在 Coliru 上查看和编译
使用指示的行,我收到以下错误:
c++ - 以 nullptr 作为参数的函数重载解析
考虑下面的代码。fun
尽管接受指针的两个重载,传递nullptr
到fun
都不会导致任何编译错误。然而,非常相似的函数bun
无法编译。当我i
使用打印参数的类型时typeid(i).name()
(在修改代码只是为了打印它之后)我得到相同的类型,只是int*
. 在 case 中解决歧义fun
但失败的规则是什么bun
?提前致谢!
c++ - 模棱两可的重载函数仅因参数的模板形参不同
考虑以下代码:
我将如何重写它以使其不会导致“错误 C2668:对重载函数的模糊调用”?
注意:例如,我也希望能够传入一个子类SmartPointer<SubclassOfDataWrapper>
,并将其解析为超类的重载函数。
c++11 - 无法理解(并修复)为什么存在此警告“重载 xxx 的调用不明确”
我一直在修复这个 gcc 警告:我得到了方法“registerCalBack”的树版本,它们每个都采用通过 std::function 引入的不同“可调用”。根据我声明的各种可调用类型,我可以编译或不编译,gcc 发出警告“重载 registerCallBackxxxxx 的调用不明确”。
我知道编译器可以通过考虑参数而不是返回类型来解决重载,但在这种情况下,我无法理解为什么 gcc 会出现歧义:对我来说,每个 TCallBack ... 我定义的参数都不同,当我改变时第三个的返回类型,它编译......这真的让我很困惑。我想问题的一部分来自于一些参数实际上是不完整类型的事实,但这是从 SDL 标头访问它们的方式,所以我复制了我在这个线程中提供的示例。
在代码中的注释中,您获得了已编译的定义示例和其他未编译的定义示例。
我希望你们中的一些人会比我更好地理解,现在我不知道在哪里看。提前谢谢了。
这里要编译的 gcc 命令行:
P。
c++ - 带有可变参数包的函数的 C++ 部分模板参数推导在 Clang 和 MSVC 中产生模棱两可的调用
考虑以下代码片段(可在编译器 epxlorer上获得):
它对于 GCC 编译得非常好,对于 Clang 和 MSVC 都失败了(编译器说ambiguous call)
为什么 Clang 和 MSVC 无法进行如此看似明显的推论?
编辑:GCC 为我作为用户提供了预期的解决方案,是否有一种简单的方法可以推动 clang 和 msvc 选择模板而无需对原始代码进行太多更改?