- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有一小段 C++11 代码,g++(4.7 或 4.8)拒绝编译,声称对 B2 b2a(x, {P(y)}) 的构造函数的调用不明确。 Clang++ 对这些代码很满意,但拒绝编译 B2 b2b(x, {{P(y)}}) 而 g++ 很乐意编译!
两个编译器都非常满意以 {...} 或 {{...}} 作为参数的 B1 构造函数。任何 C++ 语言律师都可以解释哪个编译器是正确的(如果有的话)以及发生了什么?代码如下:
#include <initializer_list>
using namespace std;
class Y {};
class X;
template<class T> class P {
public:
P(T);
};
template<class T> class A {
public:
A(initializer_list<T>);
};
class B1 {
public:
B1(const X&, const Y &);
B1(const X&, const A<Y> &);
};
class B2 {
public:
B2(const X &, const P<Y> &);
B2(const X &, const A<P<Y>> &);
};
int f(const X &x, const Y y) {
B1 b1a(x, {y});
B1 b1b(x, {{y}});
B2 b2a(x, {P<Y>(y)});
B2 b2b(x, {{P<Y>(y)}});
return 0;
}
$ clang++ -stdlib=libc++ -std=c++11 test-initialiser-list-4.cc -o test.o -c
test-initialiser-list-4.cc:32:6: error: call to constructor of 'B2' is ambiguous
B2 b2(x, {{P<Y>(y)}});
^ ~~~~~~~~~~~~~~
test-initialiser-list-4.cc:26:5: note: candidate constructor
B2(const X &, const P<Y> &);
^
test-initialiser-list-4.cc:27:5: note: candidate constructor
B2(const X &, const A<P<Y>> &);
^
test-initialiser-list-4.cc: In function 'int f(const X&, Y)':
test-initialiser-list-4.cc:32:21: error: call of overloaded 'B2(const X&, <brace-enclosed initializer list>)' is ambiguous
B2 b2(x, {P<Y>(y)});
^
test-initialiser-list-4.cc:32:21: note: candidates are:
test-initialiser-list-4.cc:27:5: note: B2::B2(const X&, const A<P<Y> >&)
B2(const X &, const A<P<Y>> &);
^
test-initialiser-list-4.cc:26:5: note: B2::B2(const X&, const P<Y>&)
B2(const X &, const P<Y> &);
^
最佳答案
首先是代码,然后是我认为应该发生的事情。 (在接下来的内容中,我将忽略第一个参数,因为我们只对第二个参数感兴趣。在您的示例中,第一个参数始终是完全匹配的)。请注意,规范中的规则目前在不断变化,所以我不会说一个或另一个编译器有错误。
B1 b1a(x, {y});
const Y&
C++11 中的构造函数,因为
Y
是一个聚合和
Y
没有
Y
类型的数据成员(当然)或其他可由它初始化的东西(这是丑陋的东西,正在努力修复 - C++14 CD 还没有对此的措辞,所以我不确定最终的 C++14将包含此修复程序)。
const A<Y>&
的构造函数可以调用参数 -
{y}
将作为
A<Y>
的构造函数的参数,并将初始化该构造函数的
std::initializer_list<Y>
.
B1 b1b(x, {{y}});
const Y&
的构造函数计数。范围。
const A<Y>&
的构造函数,有点复杂。计算初始化成本的重载决议中的转换成本规则
std::initializer_list<T>
要求花括号列表的每个元素都可以转换为
T
.然而我们之前说过
{y}
无法转换为
Y
(因为它是一个聚合)。现在重要的是要知道
std::initializer_list<T>
是不是聚合。坦率地说,我不知道根据标准库条款是否必须将其视为聚合。
std::initializer_list<Y>
的复制构造函数。 ,然而这将再次触发完全相同的测试序列(导致重载决议检查中的“无限递归”)。由于这相当奇怪且无法实现,我认为任何实现都不会走这条路。
std::initializer_list
作为一个聚合,我们会说“不,没有找到转换”(参见上面的聚合问题)。在这种情况下,由于我们不能将单个初始化列表作为一个整体调用初始化构造函数,
{{y}}
将被拆分为多个参数,以及
A<Y>
的构造函数将分别考虑其中的每一个。因此,在这种情况下,我们最终会得到
{y}
初始化
std::initializer_list<Y>
作为单个参数 - 这非常好并且像魅力一样工作。
std::initializer_list<T>
是一个聚合,这很好,成功调用第二个构造函数。
B2 b2a(x, {P<Y>(y)});
Y
那样的聚合问题。不再,因为
P<Y>
有一个用户提供的构造函数。
P<Y>
参数构造函数,该参数将由
{P<Y> object}
初始化.如
P<Y>
没有初始化列表,列表将被拆分为单独的参数并调用
P<Y>
的移动构造函数右值对象为
P<Y>
.
A<P<Y>>
参数构造函数,与上面的情况相同,有
A<Y>
由
{y}
初始化: 自
std::initializer_list<P<Y>>
可以通过
{P<Y> object}
初始化,参数列表没有被拆分,因此大括号用于初始化构造函数的 S
std::initializer_list<T>
.
struct X { operator int(); X(){/*nonaggregate*/} };
void f(X);
void f(int);
int main() {
X x;
f({x}); // ambiguity!
f(x); // OK, calls first f
}
{x}->X
来实现的成为身份转换(如
X->x
)。目前,它是一个用户定义的转换。
B2 b2b(x, {{P<Y>(y)}});
const P<Y>&
的构造函数,我们再次拆分参数并得到
{P<Y> object}
传递给
P<Y>
的构造函数的参数.请记住
P<Y>
有一个复制构造函数。但这里的复杂之处在于我们不允许使用它(参见 13.3.3.1p4),因为它需要用户定义的转换。剩下的唯一构造函数是使用
Y
的构造函数。 ,但是一个
Y
不能被
{P<Y> object}
初始化.
A<P<Y>>
的构造函数,
{{P<Y> object}}
可以初始化一个
std::initializer_list<P<Y>>
, 因为
{P<Y> object}
可转换为
P<Y>
(除了上面的
Y
- dang,聚合)。
std::initializer_list<T>
是一个聚合,这很好,成功调用第二个构造函数 关于C++11 构造函数重载解析和初始化列表 : clang++ and g++ disagree,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17704732/
我是 Spring 新手,这就是我想要做的事情: 我正在使用一个基于 Maven 的库,它有自己的 Spring 上下文和 Autowiring 字段。 它的bean配置文件是src/test/res
我在我的测试脚本中有以下列表初始化: newSequenceCore=["ls", "ns", "*", "cm", "*", "ov", "ov", "ov", "ov", "kd"] (代表要在控
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Class construction with initial values 当我查看 http://en.
我得到了成员变量“objectCount”的限定错误。编译器还返回“ISO C++ 禁止非常量静态成员的类内初始化”。这是主类: #include #include "Tree.h" using n
我有如下所示的a.h class A { public: void doSomething()=0; }; 然后我有如下所示的b.h #include "a.h" class b: publi
我需要解析 Firebase DataSnapshot (一个 JSON 对象)转换成一个数据类,其属性包括 enum 和 list。所以我更喜欢通过传递 DataSnapshot 来手动解析它进入二
我使用 JQuery 一段时间了,我总是使用以下代码来初始化我的 javascript: $(document).ready( function() { // Initalisation logic
这里是 Objective-C 菜鸟。 为什么会这样: NSString *myString = [NSString alloc]; [myString initWithFormat:@"%f", s
我无法让核心数据支持的 NSArrayController 在我的代码中正常工作。下面是我的代码: pageArrayController = [[NSArrayController alloc] i
我对这一切都很陌生,并且无法将其安装到我的后端代码中。它去哪里?在我的页脚下面有我所有的 JS? 比如,这是什么意思: Popup initialization code should be exec
这可能是一个简单的问题,但是嘿,我是初学者。 所以我创建了一个程序来计算一些东西,它目前正在控制台中运行。我决定向其中添加一个用户界面,因此我使用 NetBeans IDE 中的内置功能创建了一个 J
我有 2 个 Controller ,TEST1Controller 和 TEST2Controller 在TEST2Controller中,我有一个initialize()函数设置属性值。 如果我尝
据我所知, dependentObservable 在声明时会进行计算。但如果某些值尚不存在怎么办? 例如: var viewModel ={}; var dependentObservable1 =
我正在阅读 POODR 这本书,它使用旧语法进行默认值初始化。我想用新语法实现相同的功能。 class Gear attr_reader :chainring, :cog, :wheel de
我按照 polymer 教程的说明进行操作: https://www.polymer-project.org/3.0/start/install-3-0 (我跳过了可选部分) 但是,在我执行命令“po
很抱歉问到一个非常新手的Kotlin问题,但是我正在努力理解与构造函数和初始化有关的一些东西。 我有这个类和构造函数: class TestCaseBuilder constructor(
假设我们有一个包含 30 列和 30 行的网格。 生命游戏规则简而言之: 一个小区有八个相邻小区 当一个细胞拥有三个存活的相邻细胞时,该细胞就会存活 如果一个细胞恰好有两个或三个活的相邻细胞,那么它就
我是 MQTT 和 Android 开放附件“AOA” 的新手。在阅读教程时,我意识到,在尝试写入 ByteArrayOutputStream 类型的变量之前,应该写入 0 或 0x00首先到该变量。
我有 2 个 Controller ,TEST1Controller 和 TEST2Controller 在TEST2Controller中,我有一个initialize()函数设置属性值。 如果我尝
我有一个inotify /内核问题。我正在使用“inotify” Python项目进行观察,但是,我的问题仍然是固有的关于inotify内核实现的核心。 Python inotify项目处理递归ino
我是一名优秀的程序员,十分优秀!