首页 > 解决方案 > 谁在`std::initializer_list`上?铿锵++还是g++?

问题描述

在与一个我无法让std::initializer_list逻辑按预期工作的程序进行了长时间的斗争之后,我最终得到了一个小案例,我发现clang++6.0.1 和g++8.2.0 都在编译,但语义不同。

哪一个是正确执行该标准的?我试图通过阅读相关部分来自己理解规则,但我的大脑在尝试中爆炸了......

#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指针被初始化),而clang++只是调用复制构造函数x

活生生的例子:

标签: c++g++language-lawyerclang++stdinitializerlist

解决方案


推荐阅读