C ++ 14 GCC首选使用std :: initializer_list的构造函数,而不是move-constructor

我遇到了无法解释的情况。
我通过一个简短的示例成功重现了该问题:
我的类myobj(最初为nlohmann :: json)具有2个构造函数:move构造函数和接收std :: initializer_list的构造函数。
gcc编译器总是更喜欢std :: initializer_list的构造函数,而clang更喜欢move构造函数。

可以在在线编译器中复制该示例:http://coliru.stacked-crooked.com/
编译行:g ++ -std = c ++ 14 -O0 -pthread main.cpp && ./a.out
clang ++ -std = c ++ 14 -O0 -pthread main.cpp && ./a.out

#include <iostream>
#include <initializer_list>

template <class T>
class MyUnion
{
public:

    MyUnion(T&& t): _t{std::move(t)} {}

    T _t;
};

struct myobj
{
    myobj() : _a(0) { std::cout << "ctor" << std::endl; }

    myobj(myobj&& r) : _a(std::move(r._a)) { std::cout << "m.ctor" << std::endl; }

    myobj(const myobj&& r) : _a(std::move(r._a)) { std::cout << "cm.ctor" << std::endl; }

    myobj(const myobj& r) : _a(r._a) { std::cout << "c.ctor" << std::endl; }

    myobj(std::initializer_list<myobj> l) : _a(0) { std::cout << "ctr(list)" << std::endl; }

    ~myobj() { std::cout << "~dtor" << std::endl; }

    int _a;
};

int main()
{
    std::cout << "myobj" << std::endl;

    myobj a{myobj{}};

    std::cout << "\nmyUnion" << std::endl;

    MyUnion<myobj> u1{myobj{}};

    std::cout << "\nfinish" << std::endl;
    return 0;
}

gcc输出:

myobj
ctor
ctr(list)
~dtor

MyUnion
ctor
m.ctor
ctr(list)
~dtor
~dtor

finish
~dtor
~dtor

c声输出:

myobj
ctor

MyUnion
ctor
m.ctor
~dtor

finish
~dtor
~dtor
jjjjj662002 回答:C ++ 14 GCC首选使用std :: initializer_list的构造函数,而不是move-constructor

在存在列表初始化的情况下,与其他构造函数相比,选择初始构造函数列表的构造函数优先(请参阅here作为参考)。

本文链接:https://www.f2er.com/2493569.html

大家都在问