我对某些 C++ 标准合规性或缺乏它有疑问。
在我的项目中,我使用了一些使用 const 引用技巧的简单 Guard 类。我正在使用 Visual Studio 2005,有两种配置 - 一种用于正常发布版本,另一种用于单元测试。
在这两种情况下,最后都会在 const 引用上临时挂起,但同时发生的事情就是问题所在。对于发布配置, const 引用直接指向在创建 Guard 实例的辅助函数模板的返回中创建的 temp(没有调用复制构造函数,甚至没有实例化)。
但是对于单元测试 conf,首先复制函数模板 temp,然后调用它的析构函数,只有在 const 引用超出范围后才应该做的事情。
我已经通过禁用基类复制构造函数中的原始保护解决了这个问题(所以析构函数中的操作不会为调用复制构造函数的配置触发),但困扰我的是:
复制临时行为是否符合标准?标准是否告诉 const 引用应该直接指向 temp,或者标准中没有指定这种实现定义的行为?
我的代码大致基于 DDJ 中的 Scope Guard 文章和 Herb Sutter 的 gotw 88 文章,但是这两个来源似乎都没有考虑到早期的析构函数调用。
来自知识渊博的人的任何信息将不胜感激。
编辑:
好的,代码是这样的:
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;