我对某些C ++标准合规性或缺乏疑问有疑问。

在我的项目中,我使用了一些使用const参考技巧的简单护罩类。我正在使用Visual Studio 2005,有两种配置 - 一种用于普通释放构建,第二种用于单位测试。

在这两种情况下,最终都有一些临时挂在const参考上,但是同时发生的是问题。对于释放配置,const引用点直接指向创建卫星实例的辅助函数模板中创建的温度(没有调用复制构造函数,甚至没有实例化)。

但是对于单位测试conf,首先复制函数模板温度,然后称呼其驱动器,只有在const引用范围范围内才能完成的操作。

我通过在基类复制构造器中禁用原始防护措施解决了问题(因此,destructor中的操作并未触发copy构造函数的配置),但是令我困扰的是:

是否符合标准的副本行为?该标准是否告诉常量参考应直接指向温度,还是该实现定义的行为未指定标准中?

我的代码大致基于DDJ和Herb Sutter的GOTW 88文章的范围后卫文章,但是这两个消息来源似乎都没有考虑到较早的Destructor呼叫。

任何知识渊博的人提供的任何信息将不胜感激。

编辑:

好的,代码就是这样:

class GuardBase
{
public:

  GuardBase() : m_enabled(true)
  {}

  //this is done because in normal build no copy constructor is called ( directly using the function temporary)
  //but for UT conf somehow the original temp is copied and destroyed
  GuardBase(const GuardBase& other)
  {
    other.disable();
  }

  void disable() const
  {
    m_enabled = false;
  }

protected:
  //member is mutable because we will access the object through the const reference
  mutable bool m_enabled;
};

template< typename Arg, typename ObjType, typename MemberMethod >
class Guard1Arg : public GuardBase 
{
public:
  Guard1Arg(ObjType& obj, MemberMethod remover,  Arg arg) : m_arg(arg), m_remover(remover), m_object(obj)
  {}

  ~Guard1Arg()
  {
    if ( m_enabled )
    {
      (m_object.*m_remover)(m_arg);
    }
  }

private:
  Arg m_arg;
  MemberMethod m_remover;
  ObjType& m_object;

  //this class should not be assigned
  Guard1Arg& operator=(const Guard1Arg& other);

};

//utility template function used to create Guards using member functions with 1 argument
template<typename MemberFunction, typename Obj, typename Arg>
Guard1Arg<Arg, Obj, MemberFunction> MakeGuard1Arg(Obj& obj, MemberFunction memberFunction, Arg& arg)
{
  return Guard1Arg<Arg, Obj, MemberFunction>(obj, memberFunction, arg);
}


#define GUARD_CREATE(arg, remover) const GuardBase& guard = MakeGuard1Arg(*this,  remover, arg);
#define GUARD_DISABLE guard.disable();
#define GUARD_FRIEND template< typename Arg, typename ObjType, typename MemberMethod > friend class Guard1Arg;
有帮助吗?

解决方案

两种行为都是符合标准的。如果您有这样的代码:

T foo()
{
  return T();
}

int main()
{
  const T& x = foo();
}

然后,从概念上讲, foo, ,创建一个临时对象。此临时性被复制到返回价值 foo. 。在 main, ,此副本(这也是临时对象)约会 x.
是返回价值的副本 foo 延长其寿命,但没有临时是该副本的来源。

但是,C ++标准明确允许冗余临时对象得到消除。因此 foo 可以直接在该插槽中创建临时性。
这两个选项都是可能的,并且在使用哪个选项时,编译器甚至不必记录。

C ++标准的相关部分为6.6.3([STMT.Return])和12.2([class.temporary])。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top