C++ 如何从成员初始化列表调用随机生成器的seed_seq构造函数?

C++ 如何从成员初始化列表调用随机生成器的seed_seq构造函数?,c++,c++11,visual-c++,std,c++-standard-library,C++,C++11,Visual C++,Std,C++ Standard Library,我有一个带有std::mersenne_twister_engine成员的类,我想用一个由字符串构造的std::seed_seq初始化它。最初我试过这样做: class A { private: std::mt19937_64 rng; public: A(std::string seed) : rng(std::seed_seq(seed.begin(), seed.end())) { } }; 但这无法编译,因为: (…)无法将参数1从'std::seed_seq'转换为'

我有一个带有
std::mersenne_twister_engine
成员的类,我想用一个由字符串构造的
std::seed_seq
初始化它。最初我试过这样做:

class A
{
private:
    std::mt19937_64 rng;
public:
    A(std::string seed) : rng(std::seed_seq(seed.begin(), seed.end())) { }
};
但这无法编译,因为:

(…)无法将参数1从'std::seed_seq'转换为'seed_seq&'
我可以让它像这样工作:

class B
{
private:
    std::mt19937_64 rng;
public:
    B(std::string seed) {
        std::seed_seq seedSeq(seed.begin(), seed.end());
        rng = std::mt19937_64(seedSeq);
    }
};
class C
{
private:
    std::mt19937_64 rng;
    const std::seed_seq& makeSeedSeq(std::string seed)
    {
        return std::seed_seq(seed.begin(), seed.end());
    }
public:
    C(std::string seed) : rng(makeSeedSeq(seed)) { }
};
但是如果我理解正确,成员变量
rng
现在将被构造两次,因此如果可能,我希望避免这种情况所以,我的主要问题是:是否可以在不初始化
rng
两次的情况下完成这项工作

在任何人提出建议之前,我还尝试使用单独的成员函数来构造
std::seedseq
对象,但我能让它编译的唯一方法是返回一个常量ref,如下所示:

class B
{
private:
    std::mt19937_64 rng;
public:
    B(std::string seed) {
        std::seed_seq seedSeq(seed.begin(), seed.end());
        rng = std::mt19937_64(seedSeq);
    }
};
class C
{
private:
    std::mt19937_64 rng;
    const std::seed_seq& makeSeedSeq(std::string seed)
    {
        return std::seed_seq(seed.begin(), seed.end());
    }
public:
    C(std::string seed) : rng(makeSeedSeq(seed)) { }
};

C
进行编译,但是当使用不同的字符串进行测试时,结果总是相同的,并且总是好像种子是空字符串一样。我猜这是因为
makeSeedSeq
返回对本地的引用,结果是未定义的行为这是一个旁白,但是如果有人能够解释这一点,也许还有为什么
std::seed\u seq
以这种方式实现,我将非常感激。

只需在
std::mt19937\u 64
之前的类中添加
std::seed\u seq
变量(变量初始化顺序很重要):

A类
{
私人:
标准::seed_seq seed_seq;
标准:mt19937\U 64 rng;
公众:
A(标准::字符串常量和种子)
:seed_seq(seed.begin(),seed.end())
,rng(种子)
{}
标准::uint32_t统一标准()
{
返回std::uniform_int_distribution()(rng);
}
};

另外,我建议在构造函数中使用
const&
,以避免执行
std::string
复制构造函数。

对于类
C
,请查看此类的第一条注释。引文:“请不要通过引用返回局部变量,[..]-”@Michiel:我主要是想在那里编译一些东西,我认为悬空引用可能是一个问题,因此我猜测意外的结果正是由于这个原因导致的未定义的行为。然而,我还记得读到过这样一篇文章:临时对象的生存期被扩展为对它的常量引用的生存期。我不确定这是否适用于这里,但如果是这样,这可能毕竟是有效的代码。这就是问号