Что делает add_lvalue_reference? - PullRequest
       3

Что делает add_lvalue_reference?

7 голосов
/ 24 февраля 2011

У меня есть этот класс, который создает путь для симулятора Монте-Карло, где он создает пути целых чисел из массива доступных целых чисел. Так, например, мы можем получить путь длиной 3 из массива, содержащего {0,1,2,3,4}, и это, например, сгенерирует 3,1,2 и 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;

};

Теперь я не совсем уверен, что мой коллега сделал с помощью typedef typename add_lvalue_reference<randgen>::type randgen_ref_t;

Что делает add_lvalue_reference? Это необходимо для работы кода?

Я не видел этого раньше, поэтому любая оценка приветствуется!

1 Ответ

7 голосов
/ 24 февраля 2011

Копирование генераторов псевдослучайных чисел означает, что вы получите один и тот же поток «случайных» чисел от каждого, что нежелательно, поэтому вам нужна ссылка там.

Однако, вы могли быпросто скажите randgen&.

Согласно [dcl.ref] в черновике 3225, просто randgen& создаст ссылку lvalue независимо от того, что передано (type, lvalue-reference-type или rvalue-ссылочный тип), поэтому я бы просто использовал это.

Цитата из стандарта, который управляет этим поведением:

Если typedef (7.1.3), тип шаблон-параметр (14.3.1) или decltype-specier (7.1.6.2) обозначает тип TR, который являетсяссылка на тип T, попытка создать тип «lvalue ссылка на cv TR» создает тип «lvalue ссылка на * 1032»*T », при попытке создать тип« rvalue ссылка на cv TR »создается тип TR.

[Пример:

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&

- конец примера]

Из раздела [meta.trans.ref]:

template <class T> struct add_lvalue_reference; Если T называет объект или тип функции, тогда член typedef type должен назвать T&;в противном случае, если T называет тип «rvalue ссылка на T1», тогда член typedef type должен назвать T1&;в противном случае type должен называть T.

Это одно и то же.

В C ++ 03 они тоже одно и то же,С [type.arg.type]:

Если аргумент шаблона для параметра шаблона T называет тип «ссылкой на cv1 S », попытка создать тип« ссылка на cv2 T »создает тип« ссылка на cv12 S ”, где cv12 - объединение cv-квалификаторов cv1 и cv2 .Резервные cv-квалификаторы игнорируются.

[Пример:

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

- конец примера]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...