我有这个类为montecarlo模拟器创建一个路径,它从一个可用的int数组创建整数路径。因此,例如,我们可以从包含{0,1,2,3,4}的数组中获取长度为3的路径,例如,这将生成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有什么作用? 这对于使代码有效是必要的吗?
我之前没有见过这个,所以任何见解都值得赞赏!
答案 0 :(得分:7)
复制伪随机数生成器意味着你从每个生成器获得相同的“随机”数字流,这是不可取的,所以你需要在那里引用。
然而,你可以说randgen&
。
根据草案3225中的[dcl.ref]
,只要randgen&
创建一个左值引用,无论传入什么(type,lvalue-reference-type或rvalue-reference-type),所以我' d只是使用它。
引用控制此行为的标准:
如果 typedef (7.1.3),类型模板参数(14.3.1),或 decltype-speci fi er ( 7.1.6.2)表示类型
TR
,它是对类型T
的引用,尝试创建类型“左值引用< em> cvTR
“创建类型 “左值引用T
”,同时尝试创建类型“对 cvTR
的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
命名对象或函数类型,则成员typedeftype
应命名为T&
;否则,如果T
将类型命名为“T1
的右值引用”,则 成员typedeftype
应命名为T1&
;否则,类型应命名为T
。
它们完全相同。
在C ++ 03中,它们也是一样的。来自[type.arg.type]
:
如果模板参数
T
的模板参数命名类型为“ cv1S
“,尝试创建该类型 “对 cv2T
的引用”会创建“ cv12S
的类型” “,其中 cv12 是cv-quali firs cv1 和 cv2 的联合体。 冗余的cv-quali firs被忽略。[例如:
template < class T > class X {
void f( const T &);
/ ∗ . . . ∗ /
};
X< int & > x; / / X<int&>::f has the parameter type const int&
- 结束示例]