禁止将const的指针/引用转换为C ++中的临时对象(无C ++ 0X)

时间:2010-11-09 12:36:01

标签: c++ boost metaprogramming

我面临以下问题。考虑以下课程:

//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。)

4 个答案:

答案 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;
};