【问题标题】:Disallow taking pointer/reference to const to a temporary object in C++ (no C++0X)禁止将指针/引用指向 C++ 中的临时对象(无 C++0X)
【发布时间】:2010-11-09 12:36:00
【问题描述】:

我面临以下问题。考虑以下类:

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

【问题讨论】:

    标签: c++ boost metaprogramming


    【解决方案1】:

    不,即使使用正常的引用,您的代码也可能被破坏。只需记录一个事实,即传递的对象必须是持久的。

    double *x = new double;
    Ref<double> ref(*x);
    delete x;    
    

    【讨论】:

    • +1。在文档中明确说明它必须如何使用。但是,你没有责任对你的类的滥用负责。
    • 这个限制的目的是为了帮助用户。由于在这种情况下帮助用户非常容易,我认为不应该立即放弃它。如果出于某种原因它毕竟对用户没有帮助,请详细地忽略它;-)
    【解决方案2】:

    您可能不喜欢使用它的语法,但让构造函数采用指针而不是引用。您甚至不能将 const 指针指向临时对象。

    至少,不是没有通过另一个包装器走私它,这可能会使代码明显错误(TM):template &lt;typename T&gt; T *reftoptr(T &amp;t) { return &amp;t; }

    也就是说,如果您以 reference_wrapper 的方式使用它,您的用户实际上可能想要捕获临时对象。只要 Ref 对象也是与其捕获的临时对象相同的完整表达式中的临时对象,我认为就可以了。比如,

    some_algorithm(iterator, anotherit, static_cast<Ref<const double> >(fun()));
    

    【讨论】:

    • 这是(对我而言)最接近所述问题的(也有一些有趣的考虑,尤其是最新的),谢谢你的帮助!
    【解决方案3】:

    使用指针参数来初始化您的指针成员。不要为此使用 (const) 引用 - 使用指针来初始化指针。

    过去我在跟踪引用时遇到过一些问题,虽然它与您的问题没有直接关系,但您可能会发现这两个线程很有趣:

    【讨论】:

      【解决方案4】:

      您可以使用模板。 U&amp; 被推导出为double&amp;,并且不会绑定到右值。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-14
        • 1970-01-01
        • 1970-01-01
        • 2015-02-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多