为什么在这种情况下"自动"不起作用?

Why does "auto" not work in this case?

本文关键字:不起作用 自动 为什么 这种情况下      更新时间:2023-10-16

我将从长期缺席中回到c++,同时拿起c++11和boost::asio。

在GotW#93和#94之后,我自然会对使用auto感到兴奋。

想象一下,当这个没有编译时,我的错误:

auto io = boost::asio::io_service{};

但我必须使用这个:

boost::asio::io_service io{};

为什么第二个编译,而第一个不编译?我得到的错误是

Call to implicitly-deleted copy constructor of 'boost::asio::io_service'

boost::asio::deadline::timer表现出相同的行为,但boost::posix_time::seconds没有。

(我使用的是xcode+clang+boost 1_55_0)。

完整编译示例,修改自boost asio教程:

#include <iostream>
#include <memory>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
namespace asio = boost::asio;
int main(int argc, const char * argv[]) {
    using error_code = const boost::system::error_code;
    asio::io_service io{};
    asio::deadline_timer t{io, boost::posix_time::seconds{2}};
    int count = 0;
    std::function<void (const error_code&)> fn = [&](const error_code& e) {
        if (count < 5) {
            std::cout << "Hello World" << std::endl;
            ++(count);
            t.expires_at(t.expires_at() + boost::posix_time::seconds{1});
            t.async_wait(fn);
        }
    };
    t.async_wait(fn);
    io.run();
    std::cout << "Final count is " << count << std::endl;
    return 0;
}

asio::io_service派生自不可复制,这意味着复制构造函数被故意设置为不可访问。出于同样的原因,这种说法不起作用:

boost::asio::io_service io = boost::asio::io_service{};

在这种情况下,问题不是因为auto关键字,而是缺乏对所需构造函数的访问权限。教程代码使用公共的普通构造函数,因此编译良好。

这个错误很容易解释,它与auto的使用无关。以下代码将产生类似的错误消息:

struct foo
{
    foo() = default;
    foo(foo const&) = delete;
};
foo f = foo{};

上面的最后一行需要一个可访问的副本构造函数(即使编译器删除了副本)。

boost::asio::io_service的复制构造函数被隐式删除,可能是由于存在一个或多个不可复制的数据成员或基类。您已经有了正确的解决方案来修复错误:

asio::io_service io{};