c++ 使用auto重新分配std::bind:哪种编译器能正确编译?

n6lpvg4x  于 2023-02-26  发布在  其他
关注(0)|答案(2)|浏览(159)

MSVC编译下面的代码,而GCC和Clang不编译。

#include <iostream>
#include <functional>

class Class
{
    public:
        void display() { std::cout << "display" << std::endl; }
        void store() { std::cout << "store" << std::endl; }
};

int main()
{
    Class instance;
    // std::function<void(void)> f; // this will work
    auto f = std::bind(&Class::display, instance);
    f();
    f = std::bind(&Class::store, instance);
    f();
}

Godbolt conformance view
GCC和Clang似乎删除了复制赋值操作符。
从标准的Angular 来看,哪种编译器更正确?

quhf5bfb

quhf5bfb1#

我没有标准中的确切措辞,但是编译器错误和cppreference一起给予了一个很好的概念:
根据标准,如果类实现了移动构造函数,则隐式定义的复制构造函数将被删除。如果存在默认复制构造函数,则不会删除https://en.cppreference.com/w/cpp/language/copy_constructor
std::bind的返回类型是未指定的可复制构造类型(如果所有参数都是可复制构造的),否则是可移动构造的。https://en.cppreference.com/w/cpp/utility/functional/bind
所以我认为所有的编译器都可以自由地使用标准中未指定的部分。
顺便说一句,我将在lambda中捕获示例,而不是使用std::bind

olhwl3o2

olhwl3o22#

绑定类型的行为未指定,不属于以下类型:你可以根据占位符用一组参数调用它,它是可构造/可析构的,如果所有绑定参数都是可复制的,那么它也是可复制构造的.
就是这样。没有要求类型是可复制赋值的。因此它是...未指定的。所以 * 所有的 * 都是对的。
如果您希望代码具有可移植性,就不应该依赖于未指定的行为。

相关问题