当前位置: 首页 > 知识库问答 >
问题:

防止在不同类型的d::f中包裹lambda

哈沛
2023-03-14

我有一个类,它的构造函数采用 std::函数

我很惊讶这能起作用:

#include <functional>
#include <iostream>

template <typename T>
class Thing {
public:
  using Handler = std::function<void(T)>;

  Thing(Handler handler)
  : handler_(handler)
  {}

  Handler handler_;
};

int main() {

  Thing<double> foo([](int bar) {  // Conversion to void(int) from void(double)
    std::cout << bar;
  });

  foo.handler_(4.2);

  return 0;
}

...并在没有警告的情况下编译:

$ clang --std=c++11 -lc++ -Wall -Werror test.cc
$ ./a.out
4

看起来这样的转换可能会导致不必要的副作用。我无法想象这是一种期望的行为。


共有2个答案

尹昀
2023-03-14
匿名用户

对于非捕获 lambda,您可以依赖它们衰减为指向函数的指针这一事实。
使用以下行:

using Handler = void(*)(T);

而不是< code>Handler的当前定义。< br >这样,除非您将参数类型更改为预期的类型,否则您将收到一个错误。

换句话说,这(不)像预期的那样工作:

#include <functional>
#include <iostream>

  template <typename T>
  class Thing {
  public:
    using Handler = void(*)(T);

    Thing(Handler handler)
    : handler_(handler)
    {}

    Handler handler_;
};

int main() {
    // switch the type of bar to double and it will compile
    Thing<double> foo([](int bar) {
        std::cout << bar;
    });

    foo.handler_(4.2);
    return 0;
}

请注意,如果您有lambdas的捕获列表,此解决方案将不再有效。< br >无论如何,它解决了问题中解释的问题。

彭嘉赐
2023-03-14

您可以为参数使用仅允许转换为T的模板类:

template <typename T>
struct Strict {
    // This is a bit simplistic, but enough for fundamental types
    Strict(T t_) : t(t_) {}

    operator T() const { return t; }

    template<typename U>
    operator U() const = delete;

    T t;
};

template <typename T>
class Thing {
public:
    using Handler = std::function<void(Strict<T>)>;
    //...
};

演示

但是,请注意,使用这种方法,加宽的转换效果不佳:

// doesn't compile
Thing<int> foo{[](long long bar){});
 类似资料:
  • 我试图用JAXB从XSD生成java类。 XSD是我公司的官方XSD,因此我不能仅为我的项目修改它们。在害怕在这个网站上尝试和搜索之后,我决定直接问这个问题。 我有这个在我的XSD: 这导致了一个问题:包装。指数行已在包中定义。指数 在查看生成的代码后,我可以看到,我们有一个静态的类行,进入另一个静态的内部类行(在另一个索引下) 我得到错误的行(在顶部底部)嵌套的类型行不能隐藏封闭类型 如果名称发

  • 对于这个场景,我希望“第四个任务”在“第一个任务”下。我应该怎么做才能实现这一点?谢谢。 https://jsfiddle.net/3avqjx1e/

  • 问题内容: 首先,我必须说,我一直在此站点上寻找我的问题的答案,我发现了有关此异常的多个主题,但毕竟所有主题对我没有太大帮助,所以这就是为什么我要发布这个。 每次尝试从包裹中恢复信息时,我都会遇到“包裹不可修复”异常。这是我的班级代码。 } 和我的活动代码(此活动检索一个意图,该意图带有我刚刚指定的类型的ArrayList) } LOGCAT: 问题答案: 更改此: 对此: 编辑: 而且看起来您的

  • 我试图在包中保存对象的ArrayList(列表搁置项),以便下次打开活动时检索它。 (活动从firestore获取信息,我想减少每次打开活动时的读取次数并缩短加载时间)。 但我得到了这个错误信息: “android.os.Bundle”中的putParcelableArrayList(java.lang.String,java.util.ArrayList)不能应用于“(java.lang.Str

  • 如果我声明以下密封层次结构 没有使用模块(没有module-info.java),并尝试用Maven编译它 我知道https://openjdk.java.net/jeps/409和这个部分: 许可指定的类必须位于超类附近:在同一个模块中(如果超类在命名模块中)或在同一个包中(如果超类在未命名模块中)。 然而,Maven在编译时不应该默认使用类路径吗?这一限制是否可以避免? 如果没有,这是否开创了

  • 相比于单纯的数据对象,将context包装成一个提供一些方法的对象会是更好的实践。因为这样能提供一些方法供我们操作context里面的数据。 // dependencies.js export default { data: {}, get(key) { return this.data[key]; }, register(key, value) { this.da