在 gcc 中默认构造内联静态随机数引擎

Default-construct inline static random number engines in gcc

例如,

#include <random>

struct stru {
  //inline static std::mt19937 rnd; Oops!
  inline static std::mt19937 rnd{};  
};

int main() {

}

我看两者没有语义上的区别,clang编译都没有问题。然而 gcc 8.1 为第一个产生以下错误:

prog.cc:4:30: error: no matching function for call to 'std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>::mersenne_twister_engine()'
   inline static std::mt19937 rnd;
                              ^~~
In file included from /opt/wandbox/gcc-8.1.0/include/c++/8.1.0/random:49,
                 from prog.cc:1:
/opt/wandbox/gcc-8.1.0/include/c++/8.1.0/bits/random.h:437:11: note: candidate: 'constexpr std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>::mersenne_twister_engine(const std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>&)'
     class mersenne_twister_engine
           ^~~~~~~~~~~~~~~~~~~~~~~
/opt/wandbox/gcc-8.1.0/include/c++/8.1.0/bits/random.h:437:11: note:   candidate expects 1 argument, 0 provided
/opt/wandbox/gcc-8.1.0/include/c++/8.1.0/bits/random.h:437:11: note: candidate: 'constexpr std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>::mersenne_twister_engine(std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>&&)'
/opt/wandbox/gcc-8.1.0/include/c++/8.1.0/bits/random.h:437:11: note:   candidate expects 1 argument, 0 provided

这是一个 gcc 错误(不是我的代码也不是 libstdc++),对吧?

This is a gcc bug (not my code nor libstdc++), right?

没错。使用这个简短的片段可以更容易地复制它:

struct test {
    explicit test() {};
};

struct stru {
    inline static test t; 
};

int main() {
    test t;
}

explicit 说明符正在关闭 GCC。必须调用相同的 c'tor 来初始化静态内联成员和局部变量。然而 GCC 初始化局部变量很好,但抱怨内联静态成员。