- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
为什么下面的代码不能编译,而当我在类 A 中删除构造函数之前的显式关键字时,它可以编译?
使用 Visual Studio 2013:
enum E { e1_0, e1_1 };
template<typename T>
struct A
{
A() {}
explicit A(unsigned long) {}
A(T) {}
};
struct B
{
B() {}
B(E) {}
};
void F(B) {};
void F(A<short>) {};
void test()
{
F(e1_0);
}
错误:
1>------ Build started: Project: exp_construct_test, Configuration: Debug Win32 ------
1> exp_construct_test.cpp
1>e:\exp_construct_test\exp_construct_test.cpp(23): error C2668: 'F' : ambiguous call to overloaded function
1> e:\exp_construct_test\exp_construct_test.cpp(19): could be 'void F(A<short>)'
1> e:\exp_construct_test\exp_construct_test.cpp(18): or 'void F(B)'
1> while trying to match the argument list '(E)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
编辑: 我下载了 clang 并使用 clang-cl 编译,这两种情况都报告了错误。因此,正如评论中指出的那样,歧义介于 A<short>(short)
之间。和 B(E)
.
所以也许 VC++ 中有一个错误,当我删除 explicit
时来自 A(unsigned long)
,无论出于何种意图,编译器都会选择 B(E) 而不是引发歧义错误。谁能确认 clang 行为是符合标准的,而 VC++ 是错误的?
我加了
void G(E) {};
void G(short) {};
然后像这样调用 G:
G(e1_0);
这不会引发任何错误。为什么在这里G(E)
优先考虑,以防考生A<short>::A(short)
和 B::B(E)
, 他们是模棱两可的?
结束编辑
谢谢--joja
最佳答案
让我们一个接一个地看一下您的示例的各种变体。
原始例子调用f(e0)
.
enum E {e0, e1};
template<typename T>
struct A
{
A(); // (1)
explicit A(unsigned long); // (2)
A(T); // (3)
};
struct B
{
B(); // (4)
B(E); // (5)
};
void f(A<short>); // (6)
void f(B); // (7)
void g(E); // (8)
void g(short); // (9)
三种可能性之中
e0
到unsigned long
, 创建一个 A<short>
通过构造函数 (2) 从中调用重载 (6),e0
至 short
, 创建一个 A<hort>
从它通过构造函数 (3) 调用重载 (6) 和B
来自 e0
通过构造函数 (5) 并调用重载 (7)第一个选项不适用,因为 (2) 是 explicit
.其余两个都涉及用户定义的转换,它们被认为同样好,没有一个会偏袒另一个。调用不明确且程序格式错误。
让我们删除 explicit
从构造函数中调用 f(e0)
.
template<typename T>
struct A
{
A(); // (1)
A(unsigned long); // (2)
A(T); // (3)
};
struct B
{
B(); // (4)
B(E); // (5)
};
三个选项保持不变,但这次,所有三个选项都适用,并且调用(甚至)不明确且程序格式错误。
让我们把两个构造函数都设为explicit
并调用f(e0)
.
template<typename T>
struct A
{
A(); // (1)
explicit A(unsigned long); // (2)
explicit A(T); // (3)
};
struct B
{
B(); // (4)
B(E); // (5)
};
这使得隐式构造 A<short>
变得不可能并且调用明确指的是重载 (5)。
让我们制作B
的构造函数 explicit
也调用f(e0)
.
template<typename T>
struct A
{
A(); // (1)
explicit A(unsigned long); // (2)
explicit A(T); // (3)
};
struct B
{
B(); // (4)
explicit B(E); // (5)
};
这次,没有三种转化路径适用,因为每条转化路径都会经过 explicit
构造函数。 f
没有过载适用且程序格式错误。
调用g(e0)
.
我们这里有两种可能性:
e0
到 short
并调用重载 (9)。在这两个中,第一个选项显然是有利的,因为它不涉及转换。这个电话是明确的。 (即使构造函数 (5) 不是 explicit
。)
请注意,默认构造函数 (1) 和 (4) 实际上对本次讨论没有任何贡献。使用 GCC 4.9.1 进行测试,所有五个示例都按预期运行。
关于c++ - "explicit"构造函数对重载决议的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28748564/
在围棋中,我尝试了简单的数据库连接。我需要进口大猩猩/MUX,但我不能。。我正在使用VS代码。在cd进入我的项目目录之后,我创建了main.go并运行了go get-u githorb.com/Gor
当基类中唯一的候选构造函数被标记为explicit时,派生类的实例是否可以隐式转换为其基类的实例? 我运行了这个: struct Base { Base() {} explicit Bas
我正在尝试创建一个模板类来强制执行尺寸正确性(长度除以时间得出速度,等等)。 短篇小说:“无量纲”是可能的实例之一。如果我可以允许所有实例化显式地从 double 构造,并且进一步允许“无量纲”实例化
为什么下面的代码不能编译,而当我在类 A 中删除构造函数之前的显式关键字时,它可以编译? 使用 Visual Studio 2013: enum E { e1_0, e1_1 }; template
有人能解释一下为什么我在这里遇到编译错误 - 错误 C2558:类“std::auto_ptr”:没有可用的复制构造函数或复制构造函数被声明为“显式” #include #include #inc
目前,我的 Localizable.strings 文件的文本编码设置为UTF-8。我所有其他可本地化的文件都设置为 no explicit。 我想将 UTF-8 更改为 No explicit,这怎
请引用Wikipedia:Strategy Pattern (C++) class Context { private: StrategyInterface * strateg
是否有理由为不带任何参数的构造函数使用 explicit 关键字?它有什么作用吗?我想知道,因为我刚刚遇到了这条线 explicit char_separator() 在记录 boost::char_
我经常听到人们称赞语言、框架、结构等是“明确的”。我试图理解这个逻辑。语言、框架等的目的是隐藏复杂性。如果它让您明确指定各种细节,那么它并没有隐藏太多复杂性,只是四处移动。显式有什么好处,你如何使语言
我知道有一些关于此的帖子,但大约一年了,没有回复。实际上我们使用的是 Hibernate 4.2.1.Final 而不是 PostgreSQL 8.4。我们有两个这样的实体 实体 A(顶级层次结构类)
数据“显式”传递给函数,而方法“隐式传递”给调用它的对象。 请您解释一下这两种传递数据的方式之间的区别? java 或 c# 中的示例会有所帮助。 最佳答案 Java 和 Python 语言就是说明这
R 非常棒:精简而灵活,但又强大又开放。对于小任务,如果不必在使用前声明每个变量会很方便。但是:特别是。在较大的项目中,小的拼写错误可能会搞砸一切,甚至可能没有错误消息(参见示例)! 有解决办法吗?如
我使用 python 和 selenium 编写了一个脚本,用于单击谷歌地图侧栏中列出的一些链接。单击任何项目时,每个潜在客户所附加的相关信息都会显示在右侧区域中。剧本做得很好。但是,我使用硬编码
在同一个页面同一个步骤,如果使用“wait”会得到错误信息“NoSuchElementException:消息:无法找到名称 == rw 的元素” 如果使用“switch_to_frame”将成功切换
我有以下代码部分,它给出了明确的 null 取消引用。 uint64_t *var1 = NULL; char *var2 = NULL; //Alias transfer var1 = (uint6
我的任务是迁移 C++ 类库中的错误处理概念。以前简单返回 bool(成功/失败)的方法应修改为返回一个 Result 对象,该对象传达机器可读的错误代码和人类可读的解释(以及更多在这里无关紧要的内容
我对这行代码有疑问: class S1Es3SharedState { //lock private final Lock lock = new ReentrantLock();
当我在我的代码中使用(最近发布的)Cppcheck 1.69 时 1 ,它显示了很多我没有预料到的消息。禁用 noExplicitConstructor 证明它们都属于这种类型。 但我发现我不是唯一一
这个问题与之前的 C++11 (C++03) 标准有关。 explicit 防止从一种类型到另一种类型的隐式转换。例如: struct Foo { explicit Foo(int); };
我们正在使用的外部库包含以下显式构造函数: class Chart { public: explicit Chart(Chart::Type type, Object *parent);
我是一名优秀的程序员,十分优秀!