我面临以下问题。考虑以下课程:
//Will be similar to bost::reference_wrapper
template<class T>
class Ref {
public:
explicit Ref(T& t) : m_ptr(&t) {}
private:
T* m_ptr;
};
并且此函数返回一个双
double fun() {return 1.0;}
如果我们现在有
double x = 1.0;
const double xc = 1.0;
Ref<double> ref1(x); //OK
Ref<const double> refc1(cx); //OK
然而,到目前为止好了:
//Ref<double> ref2( fun() ); //Fails as I want it to
Ref<const double> refc2( fun() ); //Works but I would like it not to
有没有办法修改Ref(你喜欢的方式)而不是函数fun,所以最后一行返回编译时错误? 请注意,您可以修改构造函数签名(只要我能够按预期初始化Ref。)
答案 0 :(得分:3)
不,即使使用普通参考也可以破坏您的代码。只需记录传递的对象必须持久的事实。
double *x = new double;
Ref<double> ref(*x);
delete x;
答案 1 :(得分:2)
您可能不喜欢使用它的语法,但要使构造函数采用指针而不是引用。你甚至不能把const指针带到临时的。
至少,不是没有通过另一个包装器偷运它,希望使代码明显错误(TM):template <typename T> T *reftoptr(T &t) { return &t; }
也就是说,如果您按照reference_wrapper
的使用方式使用此功能,那么您的用户实际上可能想要来捕获临时用户。只要Ref对象也是与它捕获的临时对象相同的完整表达式中的临时对象,我认为它没关系。例如,
some_algorithm(iterator, anotherit, static_cast<Ref<const double> >(fun()));
答案 2 :(得分:1)
使用指针参数初始化指针成员。不要为此使用(const)引用 - 使用指针初始化指针。
我在过去跟踪引用时遇到了一些问题,虽然它与您的问题没有直接关系,但您可能会发现这两个主题很有趣:
答案 3 :(得分:0)
您可以使用模板。 U&
被推导为double&
,并且不会绑定到右值。
template<class T>
class Ref {
public:
template<typename U>
explicit Ref(U& t,
typename boost::enable_if<
boost::is_convertible<U, T&>
>::type * = 0)
: m_ptr(&t) {}
private:
T* m_ptr;
};