Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have this class that makes a path for a montecarlo simulator where it takes creates paths of integers from an array of available ints. So for example we could have a path of length 3 drawn from the array containing {0,1,2,3,4} and this would for example generate 3,1,2 and 1,4,0.

//This path generator just generates a list of ints for each path
template< typename randgen >
class MCPathGen {
    public:
        typedef vector< int > mcpath_t;
        typedef randgen randgen_t;
        typedef typename add_lvalue_reference<randgen>::type randgen_ref_t;

        MCPathGend(randgen_ref_t r) : m_rgen(r) {}

        //generate a single path by shuffling a copy of blank_d
        mcpath_t operator()() {
            Chooser< randgen_t > choose(m_rgen);
            mcpath_t path_temp(blank_d.begin(), blank_d.end());
            random_shuffle(path_temp.begin(), path_temp.end(), choose);

            return path_temp;
        };

    private:
        randgen_ref_t m_rgen;

};

Now I'm not quite sure what my colleague has done by using typedef typename add_lvalue_reference<randgen>::type randgen_ref_t;

What does add_lvalue_reference do? Is this necessary for making the code work?

I have not seen this before, so any insight is appreciated!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
237 views
Welcome To Ask or Share your Answers For Others

1 Answer

Copying pseudo-random number generators means you'd get the same stream of "random" numbers from each, which is not desirable, so you need a reference there.

However, you could just say randgen&.

According to [dcl.ref] in draft 3225, just randgen& will create an lvalue reference no matter what's passed in (type, lvalue-reference-type, or rvalue-reference-type), so I'd just use that.

Quote from the standard that controls this behavior:

If a typedef (7.1.3), a type template-parameter (14.3.1), or a decltype-speci?er (7.1.6.2) denotes a type TR that is a reference to a type T, an attempt to create the type “lvalue reference to cv TR” creates the type “lvalue reference to T”, while an attempt to create the type “rvalue reference to cv TR” creates the type TR.

[ Example:

int  i;
typedef  int&  LRI;
typedef  int&&  RRI;

LRI&  r1  =  i; // r1 has the type int&
const  LRI&  r2  =  i; // r2 has the type int&
const  LRI&&  r3  =  i; // r3 has the type int&

RRI&  r4  =  i; // r4 has the type int&
RRI&&  r5  =  i; // r5 has the type int&&

decltype(r2)&  r6  =  i; // r6 has the type int&
decltype(r2)&&  r7  =  i; // r7 has the type int&

— end example ]

From section [meta.trans.ref]:

template <class T> struct add_lvalue_reference; If T names an object or function type then the member typedef type shall name T&; otherwise, if T names a type “rvalue reference to T1” then the member typedef type shall name T1&; otherwise, type shall name T.

They are exactly the same thing.

In C++03, they're the same thing too. From [type.arg.type]:

If a template-argument for a template-parameter T names a type “reference to cv1 S”, an attempt to create the type “reference to cv2 T” creates the type “reference to cv12 S”, where cv12 is the union of the cv-quali?ers cv1 and cv2. Redundant cv-quali?ers are ignored.

[ Example:

template   < class  T >  class   X  {
void   f( const   T &);
/ ? . . . ? /
};
X< int & >  x;          / / X<int&>::f has the parameter type const  int&

— end example ]


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...