Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
244 views
in Technique[技术] by (71.8m points)

c++ - What does add_lvalue_reference do?

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

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

1 Reply

0 votes
by (71.8m points)

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 ]


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...