为什么我不能将bind声明为constexpr?

4

假设我想创建一些constexpr函数对象,我认为可以使用bind来实现。我是否忽略了什么?为什么bind不能返回constexpr

给定:

struct foo {
    int b() const { return _b; }
    int a() const { return _a; }
    int r() const { return _r; }
    const int _b;
    const int _a;
    const int _r;
};

我想要:

constexpr auto sumB = bind(plus<int>(), placeholders::_1, bind(&foo::b, placeholders::_2));
constexpr auto sumA = bind(plus<int>(), placeholders::_1, bind(&foo::a, placeholders::_2));
constexpr auto sumR = bind(plus<int>(), placeholders::_1, bind(&foo::r, placeholders::_2));

有什么我可以做的来使它工作吗?

2
问题可能现在不是“为什么不能”,而是“为什么不”。它可能可以,但它没有。 - Kerrek SB
@NathanOliver 我认为那会是一个很好的答案。你介意发一下吗? - Jonathan Mee
2个回答

5

没有技术障碍可以使bind成为constexpr;例如,Sprout C++ Libraries有一个启用constexpr的bind

然而,在标准中未指定constexpr的函数签名,实现不允许添加constexpr,目前我所知道的还没有任何关于将constexpr添加到bind的提议(C++14标准库的哪些部分可以和哪些部分将会被设为constexpr?)。这种情况相当不可能发生,因为bind已经大多数被lambda表达式替代,而从C++17开始,lambda表达式自动成为constexpr:

constexpr auto sumB = [](int x, foo const& y) { return x + y.b(); };

这很好,因为它回答了我更深层次的问题,即为什么bind的结果不能像lambda一样进行捕获,因此应该在编译时完全定义为constexpr - Jonathan Mee

3

好的,我们不知道std :: bind返回什么。它可能可以工作,但没有任何规定使其工作(在std :: bind 的规范中没有定义为constexpr)。

然而,如果您可以访问C ++ 17,则可以使用lambda表达式。在C ++ 17中,lambda表达式的operator()默认标记为constexpr,允许您执行以下操作:

constexpr auto sumB = [](auto val, auto obj) { return val + obj.b(); };
constexpr auto sumA = [](auto val, auto obj) { return val + obj.a(); };
constexpr auto sumR = [](auto val, auto obj) { return val + obj.r(); };

实时演示


std::bind 无法返回 std::function - Yakk - Adam Nevraumont
@Yakk 哇,今天我学到了。谢谢你提供的信息。回答已经被编辑过了。 - NathanOliver
如果你想知道为什么,那么std::bind的返回值必须有一个模板化的operator(),并且当传递给另一个绑定表达式时必须具有某些属性;而std::function则没有这些属性。 - Yakk - Adam Nevraumont

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接