gpt4 book ai didi

c++ - 使用 future 时获取 C2280(尝试引用已删除的函数)

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:01:45 32 4
gpt4 key购买 nike

我正在使用 poco 库,我正在尝试将它们包装到一个更好的 HTTPClient 中,我可以在几行中随处使用,并使它们异步。为此,我使用 std::future 和自定义响应结构。但是,出于某种原因,它告诉我它正在尝试引用已删除的函数。我没有删除任何东西,所以我真的不知道为什么会这样说。

http客户端.h

#include <Poco/Net/HTTPSClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Exception.h>
#include <Poco/URI.h>
#include <future>
#include <map>

typedef struct response {
std::istream& is;
Poco::Net::HTTPResponse& response;
} RES;

class HttpClient {
public:
static std::future<RES> get(Poco::Net::HTTPSClientSession& session, Poco::URI url, std::map<std::string, std::string> headers = {});
};

http客户端.cpp

#include "httpclient.h"

std::future<RES> HttpClient::get(Poco::Net::HTTPSClientSession& session, Poco::URI url, std::map<std::string, std::string> headers) {
return std::async(std::launch::async, [&session, url, headers](){
try {
std::string path(url.getPathAndQuery());
if (path.empty()) path = "/";

Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
request.add("Content-Length", "0");

if (headers.size() > 0) {
for (std::map<std::string, std::string>::const_iterator itr = headers.begin(); itr != headers.end(); ++itr) {
request.add(itr->first, itr->second);
}
}

Poco::Net::HTTPResponse _res;
session.sendRequest(request);
std::istream& is = session.receiveResponse(_res);
return RES { is, _res };
}
catch (Poco::Exception & exc) {
OutputDebugStringA(exc.displayText().c_str());
}
});
}

主要.cpp

Poco::Net::initializeSSL();

Poco::URI uri("https://www.google.com");
const Poco::Net::Context::Ptr context = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "", Poco::Net::Context::VERIFY_NONE, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), context);

std::future<RES> response = HttpClient::get(session, uri, {});
response.get();

这是我得到的精确错误:C2280: response &response::operator =(const response &)': attempted to reference a deleted function future:line 332

谢谢!

最佳答案

该错误告诉您无法复制 response 对象,而您正试图这样做。

struct response { 
std::istream& is; // can't be copied: istream( const istream&) = delete;
Poco::Net::HTTPResponse& response; // also not copyable or movable
};

但是,您显示的代码中没有任何内容尝试这样做。

receiveResponse() 返回对 std::istream 的引用,如果抛出该引用就会出现问题。当您捕捉到异常时,您没有任何可返回的东西,因此您不会 - 并进入未定义行为的领域。

您不妨读取 async lambda 中的数据并将其直接存储在您的 RES 中。

#include <Poco/Exception.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Net/HTTPSClientSession.h>
#include <Poco/Net/SecureStreamSocket.h>
#include <Poco/URI.h>

#include <future>
#include <iostream>
#include <map>
#include <vector>
#include <memory>

// a slightly modified version of your RES struct
struct RES {
std::vector<std::string> data{}; // the document data

// using a unique_ptr to make HTTPResponse easier to move
std::unique_ptr<Poco::Net::HTTPResponse>
response = std::make_unique<Poco::Net::HTTPResponse>();

bool ok = false; // if reading was done without an exception
};

class HttpClient {
public:
static std::future<RES> get(Poco::Net::HTTPSClientSession& session,
Poco::URI url,
std::map<std::string, std::string> headers = {});
};

std::future<RES> HttpClient::get(Poco::Net::HTTPSClientSession& session,
Poco::URI url,
std::map<std::string, std::string> headers) {
return std::async(std::launch::async, [&session, url, headers]() {

RES res;

try {
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET,
url.getPathAndQuery(),
Poco::Net::HTTPMessage::HTTP_1_1);

// add request headers
for(const auto&[field, value]: headers)
request.add(field, value);

session.sendRequest(request);
std::istream& is = session.receiveResponse(*res.response);

// read document data
std::string line;
while(std::getline(is, line))
res.data.push_back(line);

res.ok = true; // reading was done without an exception
} catch(Poco::Exception& exc) {
std::cout << exc.displayText().c_str() << "\n";
}

// always return according to what you declared
return res;
});
}

示例用法:

class SSLInitializer {
public:
SSLInitializer() { Poco::Net::initializeSSL(); }
~SSLInitializer() { Poco::Net::uninitializeSSL(); }
};

int main() {
SSLInitializer sslInitializer;

Poco::URI uri{"https://www.google.com/"};

const Poco::Net::Context::Ptr context = new Poco::Net::Context(
Poco::Net::Context::CLIENT_USE, "", "", "", Poco::Net::Context::VERIFY_NONE, 9,
false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");

Poco::Net::HTTPSClientSession sess(uri.getHost(), uri.getPort(), context);

std::future<RES> fut_res = HttpClient::get(sess, uri);

fut_res.wait();

RES res = fut_res.get();
std::cout << std::boolalpha << "Response OK: " << res.ok << "\n---\n";
if(res.ok) {
Poco::Net::HTTPResponse& header = *res.response

std::cout << "HTTPResponse header:\n";
for(const auto& [field, value] : header) {
std::cout << field << " = " << value << "\n";
}

std::cout << "--- DOCUMENT DATA ---\n";
for(const auto& s : res.data) {
std::cout << s << "\n";
}
}
}

关于c++ - 使用 future 时获取 C2280(尝试引用已删除的函数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58490397/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com