- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我对某些 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;
最佳答案
这两种行为都符合标准。如果您有这样的代码:
T foo()
{
return T();
}
int main()
{
const T& x = foo();
}
然后,从概念上讲,在 foo
中,创建了一个临时对象。这个临时文件被复制到 foo
的返回值中。在 main
中,这个拷贝(也是一个临时对象)绑定(bind)到 x
。
作为 foo
的返回值的拷贝的生命周期得到延长,但作为拷贝源的临时文件却没有。
但是,C++ 标准明确允许省略多余的临时对象。因此,foo
可以直接在该槽中创建临时对象,而不是创建一个临时对象并将其复制到插槽中以获取返回值。
这两个选项都是可能的,编译器甚至不需要记录它何时使用哪个选项。
C++ 标准的相关部分是 6.6.3 ([stmt.return]) 和 12.2 ([class.temporary])。
关于c++ - 用于临时延长生命周期的 const 引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4086508/
我有一个网站,用户可以在其中提交游戏报告。我目前结合使用 markdown 和 HTMLPurifier 来允许有限的标记。 我想添加内联照片支持,从用户图库中绘制图像。 我用一些 JS 构建了一个图
Name = (src.Client.Account.Rank > 65 ? src.Client.Account.Rank > 2 ? "$" : "@" : "") + src.Name, 这
在下面的例子中: http://coliru.stacked-crooked.com/a/7a1df22bb73f6030 struct D{ int i; auto test2
有没有办法延长 Firebase SMS 的过期时间?似乎只有一分钟左右有效,有时需要比这更长的时间才能收到短信。 更新:我正在通过 Web API 发送短信 最佳答案 将此视为目前的最新答案,今天已
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。 9年前关闭。 Improve this que
我正在绘制相同的 密度图 使用 基础绘图系统和 ggplot2 . 中的密度图基础绘图系统有光滑的尾部: d = density(iris$Sepal.Length) plot(d) 中的密度图ggp
大家好,我认识的每个人都问这个问题很基础而且很愚蠢,但这个问题让我很烦。如果我有以下代码。 var timerVal = 900000 function myFunction() { setTim
当我在 Rust 0.12.0 中编译以下代码时,出现以下错误: error: borrowed value does not live long enough let _ = match re.ca
我正在尝试将一个系列解析为 token 树,但是当我尝试实现我的解析特征时,我收到了与引用生命周期相关的错误。我认为创建一个盒装版本可以解决任何与引用计数或生命周期有关的问题。代码如下。 impl P
当我在 Rust 0.12.0 中编译以下代码时,出现以下错误: error: borrowed value does not live long enough let _ = match re.ca
我在方法中有以下代码: int64_t delayInSeconds = 2.0f; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
当我按下主页按钮时,我的应用程序正确暂停,但只持续几分钟。如果我离开它一会儿然后返回它,应用程序会重新启动。 我没有在我的应用程序中运行任何后台任务,其他应用程序保持暂停状态的时间比我的要长得多。 这
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 9 年前。 Improve this qu
我需要服务停止足够长的时间。大约 5-10 分钟。现在在 Windows 10 上,我的服务系统在 60 秒后终止,而没有等待它正确完成。使用网络函数 RequestAdditionalTime 看到
如何延长windows app证书的有效期?我们正在加载应用程序/主要障碍是证书每年都会过期,通过 GP 更新证书很麻烦,因为我们的环境中已经存在问题。我们希望将其延长至少 5 年。 我设法找到了关于
最近我看到了这个: 在 2037 年之前,我的任何应用都不太可能存活(而且我存活了下来,所有依赖它的东西都存活了),我的应用是否会因为需要新证书而必须使用新的包名称重新发布? 没有办法延长证书吗? 最
有什么方法可以延长 keystore 或证书的时间有效性吗? 我已经创建了一个有效期为 10 年的 keystore 。但是,由于谷歌市场的限制,我需要 30 年的有效期。 最佳答案 证书有效性是证书
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关于您编写的代码问题的问题必须在问题本身中描述具体问题 — 并且包括有效代码 以重现它。参见 SSC
我 3 天前注册了 30 天的 Azure 试用版。我有 2 个虚拟机。今天,我的管理门户中弹出 2 条消息。 您的免费试用将在 25 天后到期。单击此处立即升级。 根据您的使用历史记录(21.52
我是一名优秀的程序员,十分优秀!