在我无法使std::initializer_list
逻辑正常工作的程序中奋斗了很长时间之后,我遇到了一个小案例,发现clang++
6.0.1和{{1} } 8.2.0都在编译,但是语义不同。
正确执行标准的是哪一个?我试图通过阅读相关章节来自己理解规则,但是我的大脑在尝试中爆炸了……
g++
在特定的#include <vector>
#include <stdio.h>
struct Value {
int i;
std::vector<Value> *v;
Value() : i(0), v(nullptr) {}
Value(int x) : i(x), v(nullptr) {}
template<typename T>
Value(const std::vector<T>& x)
: v(new std::vector<Value>(x.begin(), x.end())) { }
Value(std::initializer_list<Value> L)
: Value(std::vector<Value>(L)) { }
void dump(int indent = 0) {
if (v) {
printf("%*s[\n", indent, "");
for (int i=0,n=v->size(); i<n; i++) {
(*v)[i].dump(indent + 4);
}
printf("%*s]\n", indent, "");
} else {
printf("%*s%i\n", indent, "", i);
}
}
};
int main(int argc, const char *argv[]) {
Value x; printf("x:\n"); x.dump(); printf("---\n\n");
Value y1 = x; printf("y1:\n"); y1.dump(); printf("---\n\n");
Value y2 = {x}; printf("y2:\n"); y2.dump(); printf("---\n\n");
Value y3; y3 = {x}; printf("y3:\n"); y3.dump(); printf("---\n\n");
Value y4; y4 = {{x}}; printf("y4:\n"); y4.dump(); printf("---\n\n");
return 0;
}
中将g++
初始化为值列表(y2
指针被初始化),而v
只是在{{1}上调用复制构造函数}。
实时示例: