- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
注意:
Signal1<A1>::raise(7)
Slot::operator()(7)
Slot1<A1>::operator()(7)
Handling new value: 3931764 // This value changes on each execution
Signal1<A1>::raise(7)
Slot::operator()(7)
Slot1<A1>::operator()(7)
Handling new value: 7
Signal1<A1>::raise(7)
Slot::operator()(7)
Slot1<A1>::operator()(7)
Handling new value: 7
#include <functional>
#include <iostream>
#include <vector>
// Version 1: uses perfect forwarding with std::function<void (T)>
// Version 2: uses perfect forwarding with std::function<void (const T&)>
// Version 3: forgoes perfect forwarding with std::function<void (T)>
#define VER 1
class Slot
{
public:
template<typename A1>
#if VER == 1 || VER == 2
void operator()(A1&& a1) const;
#elif VER == 3
void operator()(A1 a1) const;
#endif
};
template<typename A1>
class Slot1 : public Slot
{
public:
template<typename T>
Slot1(T* instance, void (T::*fn)(A1)) :
mFn(std::bind(fn, instance, std::placeholders::_1))
{
// Do nothing
}
void operator()(A1 a1) const
{
std::cout << "Slot1<A1>::operator()(" << a1 << ")\n";
mFn(a1);
}
private:
#if VER == 1 || VER == 3
std::function<void (A1)> mFn;
#elif VER == 2
std::function<void (const A1&)> mFn;
#endif
};
template<typename A1>
#if VER == 1 || VER == 2
void Slot::operator()(A1&& a1) const
#elif VER == 3
void Slot::operator()(A1 a1) const
#endif
{
std::cout << "Slot::operator()(" << a1 << ")\n";
#if VER == 1 || VER == 2
static_cast<const Slot1<A1>&>(*this)(std::forward<A1>(a1));
#elif VER == 3
static_cast<const Slot1<A1>&>(*this)(a1);
#endif
}
class Signal
{
public:
void connect(Slot* slot)
{
mSlots.push_back(slot);
}
std::vector<Slot*> mSlots;
};
template<typename A1>
class Signal1 : public Signal
{
public:
void raise(A1 a1)
{
std::cout << "Signal1<A1>::raise(" << a1 << ")\n";
(*mSlots[0])(a1);
}
};
class Model
{
public:
void setValue(int value)
{
mValue = value;
mValueChangedSignal.raise(value);
}
Signal1<int> mValueChangedSignal;
private:
int mValue;
};
class View
{
public:
void handleChange(int value)
{
std::cout << "Handling new value: " << value << "\n";
}
};
int main()
{
View view;
Slot1<int> slot(&view, &View::handleChange);
Signal1<int> signal;
signal.connect(&slot);
signal.raise(7);
return 0;
}
这是 Visual Studio 错误还是我做错了什么?
最佳答案
版本 1 和 2 执行未定义的行为,如 Slot::operator()
的 Slot1<int>
用 A1
调用等于int&
在 Signal1<int>
内,然后 static_cast
s 本身到 Slot1<int&>
.它不是 Slot1<int&>
,因此该转换会生成一个错误的引用,然后您会使用它,然后繁荣,无论发生什么。
请检查您的类型并停止基于参数类型的显式转换,这非常不安全且难以追踪。
我对理清 #ifdef
的困惑不感兴趣s 在你的代码中确定版本 3 是否发生类似的错误。你的设计从根本上来说是不安全的,因为相对无害的参数在传递给 Slot
的参数中发生了变化。导致未定义的行为。您不应该隐式地将推导的参数传递给 operator()
并用它来转换 this
的类型派生类型。
尊重类型转换。
以下是您的代码在情况 1 中导致的未定义行为的详 segmentation 类:
signal.raise(7);
通话
Signal1<int>::raise(int)
调用
void raise(int a1)
{
(*mSlots[0])(a1);
}
在这里a1
是 int
类型的左值.所以这个调用
插槽::运算符()(int& a1) 常量因为这就是转发引用的工作方式 -- T&&
通过了 int&
推导T
作为int&
. body 然后包含
static_cast<const Slot1<int&>&>(*this)(std::forward<int&>(a1));
转换 *this
引用Slot1<int&>
,一个与所讨论的对象无关的类。当您尝试与之交互时,会出现未定义的行为。
正如我所说,修复此问题是可能的,但您的根本问题是 Slot::operator()
中类型参数的推导不是一种合适的方式来确定 Slot
的子类型你想投 *this
进入。传递给 operator()
的表达式类型一般而言,在调用点或推导点都不明显。如果您没有完全正确地理解这种类型,结果就是未定义的行为。这通常“似乎有效”,直到发生一些完全不相关的变化并且它崩溃了。
从基础转换为派生时,您必须非常小心、明确,并记录您在每一步所做的事情。
如果有人调用您的 Slot
(这实际上是一个 Slot1<int>
)具有一个无符号整数,未定义的行为。一个 size_t,未定义的行为。无符号字符,未定义的行为。一个 uint16_t,未定义的行为。将 long long 添加到 unsigned int 中,用结果调用你,未定义的行为。一种隐式转换为 int 的类型,未定义的行为。
没有类型安全的多态性很少是一个好主意。
最重要的是,您的代码中没有充分的理由这样做。 Signal1<A1>
可以实现 connect
而不是 Signal
服用Slot1<A1>
-- 毕竟,你的类型就在那里 -- 并存储一个 Slot1<A1>
的数组而不是 Slot
的数组.鉴于唯一类型的Slot
以后不会导致未定义行为的是 Slot1<A1>
,为什么存储错误的类型呢?
关于c++ - 为什么 std::function 不能与完美转发一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31885254/
为了加速测试字谜字符串的快速输出行为,我 came up with基于质数的哈希方案——尽管它看起来像 I wasn't the first . 基本思想是将字母映射到素数,并计算这些素数的乘积。字母
我使用 Perfect Framework 创建了一个 Swift 3.0 服务器。一切都按预期进行得很好,但我正在尝试了解是否有更好的方法来做一些事情。 来自 iOS 背景,我知道总是在不同的线程中
我有一个固定大小的正方形 div,希望使用 CSS 在其中放置任意大小的图像,以便它在水平和垂直方向上都居中。横向很容易: .container { text-align: center } 对于垂直
程序员离不开终端,配置一个好看又好用的终端,可以提高工作效率. 本篇文章记录了使用 Oh My Zsh + PowerLevel9k + zsh插件 快速配置Ubuntu下默认终端的过程. 我们在
在请求处理程序中,处理例如获取 https://example.com/collections/1或 POSThttp://0.0.0.0:8080/collections 如何获取服务器地址 htt
我正在使用 perfect 和 SQLite司机和StORM作为连接器。我可以一一保存(创建)多行。为了使其更快,我想一次创建多行,我该怎么做? 最佳答案 从完美的 SQLite-StORM 和 Pe
这是我在这里的第一篇文章,所以我希望我提供所有正确的信息。 我目前正在开发一个简单的菜单应用程序,它有一个按钮控制数组(使用 MSDN 建议的控制数组的变通方法),我很难重新调整表单大小和将按钮居中。
在 androidplot XYPlot 中,如果您有较大的值(许多数字)和/或较大的字体大小,则 Y 轴上的刻度标签会被剪裁。这个(以及 X 轴上的类似问题)之前已经在这些问题中讨论过: Range
注意:我遗漏了不相关的代码 所以我目前正在研究 CCC 1996 P1,这个问题的全部目的是能够计算一个整数输入是完美数、不足数还是充数。我上面列出的代码可以工作,但是我认为它太慢了。该代码会迭代每个
我需要什么 我需要一个产生双射输出的算法。我有一个 31 位输入,需要一个伪随机 31 位输出。 我考虑过的 CRC 在其位宽内是双射的。 我查看了 Google 并找到了多项式,但找不到表格或算法。
我在 Ubuntu 14.04.1、clang-3.8 上使用 PerfectSwift我使用的是 Perfect,一切正常,但现在,我不能再编译了(但它可以在我的 mac 上编译) 错误日志是 /h
如果您对分表有以下痛点那么不妨试试我这边开源的框架sharding-core ,是否需要无感知使用分表组件,是否需要支持abp,是否需要支持自定义分表规则,是否需要支持自定义分表键,是否需要支持特定
我正在尝试确定我的 crc 与“ 理想 ”32 位 crc 的比较。 因此,我运行我的 crc 超过 100 万个完全随机的数据样本并收集了碰撞数量,我想将此数字与我可以从“ 理想 ”crc 中预期的
我正在开发一个项目,需要验证我的 URL,并偶然发现了以下正则表达式模式; /(((http|ftp|https):\/{2})+(([0-9a-z_-]+\.)+(aero|asia|biz|cat
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 4 年前。 Improve
我正在创建一个需要居中于中间的圆形网站。背景由围绕中心图像的圆圈组成。每当我以全屏(F11 快捷键)查看我的网站时,无论我的屏幕分辨率如何,它都完美居中。 如果我在没有全屏显示的情况下查看我的网站,我
所以我有一个网站,在开发人员工具中测试响应能力时看起来很棒,但在 iPhone 本身上实际测试时却没有居中并且看起来有些破烂。 什么会导致这种情况,如果我无法使用 iPhone(在我的 android
我有一个内部类,它扩展了 AbstractTableModel。 import javax.swing.table.AbstractTableModel; public class MyClass e
所以我正在使用 Perfect 服务器开发一个将值返回给客户端的应用程序。目前,它需要从另一个 API 下载一些数据,对其进行处理,然后将其发送给客户端。 然而,出于某种原因,它在 OSX 中编译良好
我有一些 CSS 按钮。 “按钮”效果是通过在 anchor 标记中使用固定大小的 元素来完成的,并且 css 规则以 a span:active 、 a span:hover 的形式显示按钮状态。
我是一名优秀的程序员,十分优秀!