繁体   English   中英

std :: seed_seq编译错误(GCC错误?)

[英]std::seed_seq compilation error (GCC bug?)

我有以下几行代码,最新版本的GCC无法编译。 我非常确定它甚至没有发出警告消息。

seed_seq.cpp:

void func()
{
    std::mt19937_64 engine;
    std::hash<std::thread::id> hasher;
    uint64_t rdSeed, threadID, now;

    try
    {
        std::random_device rd;

        if (rd.entropy())
            rdSeed = rd();
        else
            rdSeed = 0;
    }
    catch (std::exception &)
    {
        rdSeed = 0;
    }

    threadID = hasher(std::this_thread::get_id());

    now = std::chrono::system_clock::now().time_since_epoch().count();

    engine.seed(std::seed_seq{ rdSeed, threadID, now });
}

命令: gcc -std=c++11 -c seed_seq.cpp -o seed_seq.o

无法编译的GCC版本:

  • gcc(GCC)6.3.1 20161221(Red Hat 6.3.1-1)
  • gcc(Ubuntu 5.4.0-6ubuntu1〜16.04.4)5.4.0 20160609

VS2013 Update 5不会抱怨。 肯定是海湾合作委员会的错吗?

我不记得曾用过的GCC版本。 抱歉。

错误:

seed_seq.cpp: In function ‘void func()’:
seed_seq.cpp:28:19: error: invalid initialization of non-const reference of type ‘std::seed_seq&’ from an rvalue of type ‘std::seed_seq’
  engine.seed(std::seed_seq{ rdSeed, threadID, now });
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/6.3.1/random:51:0,
                 from seed_seq.cpp:2:
/usr/include/c++/6.3.1/bits/random.tcc:353:7: note:   initializing argument 1 of ‘typename std::enable_if<std::is_class<_Sseq>::value>::type std::mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::seed(_Sseq&) [with _Sseq = std::seed_seq; _UIntType = long unsigned int; long unsigned int __w = 64ul; long unsigned int __n = 312ul; long unsigned int __m = 156ul; long unsigned int __r = 31ul; _UIntType __a = 13043109905998158313ul; long unsigned int __u = 29ul; _UIntType __d = 6148914691236517205ul; long unsigned int __s = 17ul; _UIntType __b = 8202884508482404352ul; long unsigned int __t = 37ul; _UIntType __c = 18444473444759240704ul; long unsigned int __l = 43ul; _UIntType __f = 6364136223846793005ul; typename std::enable_if<std::is_class<_Sseq>::value>::type = void]’
       mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          __s, __b, __t, __c, __l, __f>::
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

更新

在系统的dnf.log上找到它。 不确定是我在项目中使用过的那个...

Nov 01 18:17:41 DEBUG ---> Package gcc-gdb-plugin.x86_64 6.2.1-2.fc24 will be installed
Nov 01 18:17:42 DEBUG ---> Package gcc.x86_64 5.3.1-6.fc23 will be upgraded
Nov 01 18:17:42 DEBUG ---> Package gcc.x86_64 6.2.1-2.fc24 will be an upgrade
Nov 01 18:17:42 DEBUG ---> Package gcc-c++.x86_64 5.3.1-6.fc23 will be upgraded
Nov 01 18:17:42 DEBUG ---> Package gcc-c++.x86_64 6.2.1-2.fc24 will be an upgrade
Nov 01 18:17:42 DEBUG ---> Package libgcc.x86_64 5.3.1-6.fc23 will be upgraded
Nov 01 18:17:42 DEBUG ---> Package libgcc.x86_64 6.2.1-2.fc24 will be an upgrade                                                  
Nov 02 11:03:25 DEBUG ---> Package gcc-debuginfo.x86_64 6.2.1-2.fc24 will be installed
Nov 02 11:03:25 DEBUG ---> Package gcc-base-debuginfo.x86_64 6.2.1-2.fc24 will be installed

Jan 04 09:59:34 DEBUG ---> Package gcc.x86_64 6.2.1-2.fc24 will be upgraded
Jan 04 09:59:34 DEBUG ---> Package gcc.x86_64 6.3.1-1.fc24 will be an upgrade
Jan 04 09:59:34 DEBUG ---> Package gcc-gdb-plugin.x86_64 6.2.1-2.fc24 will be upgraded
Jan 04 09:59:34 DEBUG ---> Package gcc-gdb-plugin.x86_64 6.3.1-1.fc24 will be an upgrade
Jan 04 09:59:34 DEBUG ---> Package gcc-c++.x86_64 6.2.1-2.fc24 will be upgraded
Jan 04 09:59:34 DEBUG ---> Package gcc-c++.x86_64 6.3.1-1.fc24 will be an upgrade
Jan 04 09:59:34 DEBUG ---> Package libgcc.x86_64 6.2.1-2.fc24 will be upgraded
Jan 04 09:59:34 DEBUG ---> Package libgcc.x86_64 6.3.1-1.fc24 will be an upgrade

显然,您要传递给engine.seed()的参数就是问题所在。
我建议你看看

种子()

让我们简要地看看为什么。
如您所见,有两种方法可以调用以下定义的seed()

void seed( result_type value = default_seed );

void seed( Sseq& seq );

如果您担心gcc中存在错误,那么我认为您不应该这样做。
实际上,Clang 3.9.1(仅提及一个版本)也给出了类似的错误:

Start
prog.cc:32:12: error: no matching member function for call to 'seed'
    engine.seed(std::seed_seq{ rdSeed, threadID, now });
    ~~~~~~~^~~~
/opt/wandbox/clang-3.9.1/include/c++/v1/random:2116:10: note: candidate function not viable: no known conversion from 'std::seed_seq' to 'result_type' (aka 'unsigned long') for 1st argument
    void seed(result_type __sd = default_seed);
         ^
/opt/wandbox/clang-3.9.1/include/c++/v1/random:2124:9: note: candidate function [with _Sseq = std::__1::seed_seq] not viable: expects an l-value for 1st argument
        seed(_Sseq& __q)
        ^
1 error generated.
1
Finish

并准确指出问题所在。
我觉得不太可能,GCC和铛可能具有相同的错误,但一切是可能的。
要了解如何结合std::seed_seq调用seed() ,应查看下面的seed() ,它具有完全类似的示例。
正如您已经提到的,可以解决问题

std::seed_seq seq{ rdSeed, threadID, now };
engine.seed(seq);

或(这是冗长的方式,我可能不会这样做):

std::seed_seq seq{ rdSeed, threadID, now };
std::seed_seq& pr = seq;
engine.seed(pr);

要详细了解这种情况/错误类型,建议您阅读以下SO文章:
从类型为'int'的临时类型对类型为'int&'的非常量引用进行了无效的初始化

正如人类@Ashe在评论中指出的那样,VS2013允许它进行编译,因为它是默认情况下启用的语言扩展:应该发出警告让人们知道。 你可以在这里读更多关于它的内容:
非常量引用绑定到临时的Visual Studio错误?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM