- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
如果我有这个简单的案例:
struct Foo
{
void bar();
void baz(int );
};
这会编译是有道理的:
Foo foo;
auto f = std::bind(&Foo::bar, &foo);
但是为什么 bind
会被设计成这样:
auto g = std::bind(&Foo::baz, &foo);
我可以调用f
,但我永远不能调用g
。为什么还要进行编译?要求我必须这样做的理由是什么:
auto g2 = std::bind(&Foo::baz, &foo, std::placeholders::_1);
如果你想弄乱哪些参数被传递以及以什么顺序传递,我可以理解使用占位符,但为什么不让默认传递所有参数无需指定的正确顺序?
最佳答案
But why would bind be designed in such a way that this compiles:
auto g = std::bind(&Foo::baz, &foo);
I can callf
, but I cannot ever callg
. Why even make that compile?
Boost.Bind FAQ表示 Boost.Bind 通常会在“绑定(bind)时间”(即在您调用 bind
的那一行)诊断此类错误。然而,标准并不要求 std::bind
,而是在 std::bind
的 Requires 元素中具有以下内容:
INVOKE (fd, w1, w2, ..., wN)
(20.9.2) shall be a valid expression for some values w1, w2, ..., wN, whereN == sizeof...(bound_args)
.
这意味着您的代码违反了函数的先决条件,从而导致未定义的行为。标准库实现没有义务检查是否违反前提条件,那是你的工作。库也不禁止检查它们,因此它符合拒绝它的实现,就像 Boost.Bind 所做的那样。我会向您的库供应商提出请求,要求他们在可能的情况下诊断无效的绑定(bind)表达式,作为“实现质量”的增强。 (编辑:我让 libstdc++ 的 bind
这样做,从 GCC 5 开始。)
why not just have the default pass all the arguments in the right order without having to specify it?
我能想到两个原因。
首先,bind
创建的调用包装器的行为是丢弃不对应占位符的参数,因此您可以调用 x(1, 2, 3)
并让它忽略所有参数并调用 foo.bar()
。这是一般模式的一部分,您可以在其中使用 bind
包装 N 元函数,以创建具有完全不同元数的调用包装器,该包装器可能会添加参数、删除参数、将某些参数固定为特定绑定(bind)值等. 如果在绑定(bind)表达式中未使用占位符时的默认行为是转发所有参数,则不可能让 x(1, 2, 3)
删除所有参数。
其次,始终要求您明确说明要以何种顺序传递哪些参数更为一致。一般来说,只有在没有绑定(bind)参数的情况下传递所有调用参数才有意义,否则 bind
应该如何知道是在绑定(bind)参数之前还是之后传递调用参数?
例如给予
struct X {
void f(int, int) { }
} x;
auto h = bind(&X::f, &x, 1);
h(2);
h(2)
的调用结果应该是 x.f(1, 2)
还是 x.f(2, 1)
?由于存在绑定(bind)参数时的正确行为并不明显,因此在没有使用占位符时自动转发所有参数仅在没有绑定(bind)参数时才真正有意义(因为绑定(bind)参数应该放在最前面还是最后) ,这是一个相当特殊的情况。更改 API 的重要功能以处理该特殊情况的值(value)值得怀疑,尤其是当它使 x(1, 2, 3)
-> foo.bar()
无法实现的情况。
另一种解决方案是继续要求用户明确说明他们想要什么,但提供一种明确的方式来表达“只转发所有内容”,正如 Tomasz Kamiński 在 N4171 中提出的那样这将在下周的 C++ 委员会 session 上讨论。 _all
占位符解决了决定调用参数应该出现在绑定(bind)参数之前还是之后的问题,因为你可以明确地说你是否想要 bind(f, arg1, arg2, std::placeholders::_all)
或 bind(f, std::placeholders::_all, arg1, arg2)
甚至 bind(f, arg1, std::placeholders::_all, arg2)
关于c++ - 为什么 std::bind 不考虑功能元数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31189812/
我一直认为使用“if”比捕获异常要好得多(就性能而言)。例如,这样做: User u = Users.getUser("Michael Jordan"); if(u!=null) System.
我正在尝试使用下一个格式将字符转换为日期。我有下一个数据框 i (我在最后添加了 dput() 版本的数据框): Date 1 Dec_28_2012_9:
考虑到 PHP 中的日期戳,我如何计算持续时间?我在日期之间使用的日期格式是“Y-m-d H:i:s”, 我的工作代码只能计算时间之间的持续时间而不考虑日期。 下面是我的代码: $assigned_t
我正在尝试解释 GLMM 中的自相关。我的响应变量是 bool 值,它表示一组 hive 的生命周期中是否存在 en 事件。我试图用一组描述每个巢状态的数值变量来预测此类事件的概率。因此,我在广义模型
我对如何解释 undefined variable 感到有点困惑(我不确定你现在是否可以)。我正在尝试使用以下代码底部附近的 if else 语句(已注释掉的行)。 这个想法是,如果请求歌曲的人不是与
Bjarne Stroustrup 的 The C++ Programming Language Fourth Edition 中的以下内容是什么意思? "Consider . (dot) suspe
我想要一个主元素,边 block 漂浮在它的右侧。我不知道边 block 的数量,也不知道它们的最终总高度。但是我的主要元素应该具有相同的高度(请参阅以下示例以更好地理解),而无需使用列。 (虚线部分
我在每个 TextView 上都有以下警告(来自 Lint),在我的 XML 中有一个 ID。 Consider making the text value selectable by specify
目前,我有 6 条曲线,以 6 种不同的颜色显示,如下所示。 这 6 条曲线实际上是由 一个相同实验 的 6 次试验生成的。这意味着,理想情况下它们应该是相同的曲线,但由于噪声和不同的试验参与者,它们
winner of a recent Wikipedia vandalism detection competition建议可以通过“检测考虑到 QWERTY 的随机键盘点击来改进检测键盘布局”。 示
多年来,我一直在编写 C 语言,主要是在嵌入式环境中,并且对指针有一个非常好的心智模型——我不必明确地考虑如何使用它们,我对指针算法 100% 感到满意,指针数组,指针指针等。 我写的 C++ 很少,
我正在使用 Boost.Date_time 来获取两个日期之间的时差。我希望代码在这些天也考虑夏令时的变化,并给我正确的时间间隔。 考虑这个例子。 2015 年 11 月 1 日,美国的 DST 将发
我有一个(人类)名字的向量,全部用大写字母表示: names <- c("FRIEDRICH SCHILLER", "FRANK O'HARA", "HANS-CHRISTIAN ANDERSEN")
我想呈现一个表单小部件。这是我要生成的原始 HTML: 使用这个: {{ form_row(form.email, { 'type' : 'email', 'attr' : { 'class' :
我正在开发一个 python 项目,它使用 pythonnet 和几个 C# dll 作为依赖项。 由于我不想将 dll 推送到 git 存储库,因此我调整了 .gitignore 文件。但是,现在
考虑到上午/下午,我想将字符串转换为 php 数据时间。 我想将 '03/06/2015 12:17 am' 转换为 php datatime。 我试过了, $myDateTime = DateTim
我想排除那些具有相同标题和同一年份的实例。 title votes ranking year 0 Wonderland 19 7.9 1931 1
例如对于一个 EditText,通常指定 android:inputType="numberDecimal"用于文本字段应该包含十进制数。但这假设“。”用作小数点分隔符,在某些国家/地区使用“,”代替
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 年前。 Improv
作为练习,我决定学习 Java 中的 lambda 表达式。我想重写我发现笨拙且冗长的旧代码。它检查命令行参数是否是(1)文件路径或(2)目录路径。在(1)场景中,它将命令行参数传递给方法。在 (2)
我是一名优秀的程序员,十分优秀!