我遇到了无法解释的情况。
我通过一个简短的示例成功重现了该问题:
我的类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