无法使用两个包装不同下一层的ssl_stream编译代码

Can't compile code with two ssl_stream that wrap different next layers

本文关键字:下一层 ssl 代码 编译 stream 包装 两个      更新时间:2023-10-16

我想了解为什么在为 tcp 层创建两个包装不同对象的ssl_streams时,出现以下编译错误:

------ Build started: Project: test, Configuration: Debug x64 ------
>Microsoft (R) C/C++ Optimizing Compiler Version 19.22.27905 for x64
>Copyright (C) Microsoft Corporation.  All rights reserved.
>cl /c /I"D:workspaceopenssl-staticopenssl-OpenSSL_1_1_1aopenssl-OpenSSL_1_1_1ainclude" /ID:workspaceboostVS19boost_1_70_0 /Zi /W3 /WX- /diagnostics:column /Od /Ob0 /D WIN32 /D _WINDOWS /D _WIN32_WINNT=0x0600 /D _SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING /D "CMAKE_INTDIR="Debug"" /D _MBCS /Gm- /EHsc /RTC1 /MTd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /GR /std:c++17 /Fo"test.dirDebug\" /Fd"test.dirDebugvc142.pdb" /Gd /TP /errorReport:prompt D:workspacemain.cpp
>main.cpp
>D:workspaceboostVS19boost_1_70_0boost/beast/ssl/ssl_stream.hpp(655,5): error C2995:  'void boost::beast::teardown(boost::beast::role_type,boost::beast::ssl_stream<NextLayer> &,boost::system::error_code &)': function template has already been defined
>D:workspaceboostVS19boost_1_70_0boost/beast/ssl/ssl_stream.hpp(655): message :  see declaration of 'boost::beast::teardown'
>D:workspacemain.cpp(12): message :  see reference to class template instantiation 'boost::beast::ssl_stream<boost::asio::ip::tcp::socket>' being compiled
>D:workspaceboostVS19boost_1_70_0boost/beast/ssl/ssl_stream.hpp(668,5): error C2995:  'void boost::beast::async_teardown(boost::beast::role_type,boost::beast::ssl_stream<NextLayer> &,TeardownHandler &&)': function template has already been defined
>D:workspaceboostVS19boost_1_70_0boost/beast/ssl/ssl_stream.hpp(668): message :  see declaration of 'boost::beast::async_teardown'
>Done building project "test.vcxproj" -- FAILED.

如果两个流具有相同的模板参数(即,两者都具有 boost::beast::tcp_streamboost::asio::ip::tcp::socket),则所有错误都会消失。

#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/context.hpp>
#include <boost/beast/core/tcp_stream.hpp>
#include <boost/beast/ssl/ssl_stream.hpp>
int main() {
boost::asio::io_context ioc;
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23_client);
ctx.set_default_verify_paths();
boost::beast::ssl_stream<boost::beast::tcp_stream> stream_1(ioc, ctx);
boost::beast::ssl_stream<boost::asio::ip::tcp::socket> stream_2(ioc, ctx);
}

我想了解这是一个错误,还是所需的行为。如果是第二个,如果有人向我解释原因,那就太好了。另外,我想更好地了解在什么情况下值得使用tcp_stream,以及在哪些情况下使用套接字。

我认为这是野兽中的错误/QOI问题。它声明模板友元函数 在类声明中,即teardown.

但是模板友元并不依赖于所有类模板模板参数,因此下一次与其他模板参数ssl_stream<>实例定义了相同的模板友元函数。

简单的解决方法是使定义脱离类和朋友 仅在类主体中声明。

所以,它变成了:

template<class NextLayer>
class ssl_stream
: public net::ssl::stream_base
{
// ... many lines snipped ...
#if ! BOOST_BEAST_DOXYGEN
template<class SyncStream>
friend
void
teardown(
boost::beast::role_type role,
ssl_stream<SyncStream>& stream,
boost::system::error_code& ec);
template<class AsyncStream, class TeardownHandler>
friend
void
async_teardown(
boost::beast::role_type role,
ssl_stream<AsyncStream>& stream,
TeardownHandler&& handler);
#endif
};
template<class SyncStream>
static inline void
teardown(
boost::beast::role_type role,
ssl_stream<SyncStream>& stream,
boost::system::error_code& ec)
{
// Just forward it to the underlying ssl::stream
using boost::beast::websocket::teardown;
teardown(role, *stream.p_, ec);
}
template<class AsyncStream, class TeardownHandler>
static inline void
async_teardown(
boost::beast::role_type role,
ssl_stream<AsyncStream>& stream,
TeardownHandler&& handler)
{
// Just forward it to the underlying ssl::stream
using boost::beast::websocket::async_teardown;
async_teardown(role, *stream.p_,
std::forward<TeardownHandler>(handler));
}

我已经为此打开了一个问题+拉取请求

我打算打开一个拉取请求,但似乎相同的修复程序 (yay) 已经登陆 开发 在 1de60a046292dcd42bb0097176e0139ba4ad051b 中,该修复程序在master中并标记为boost-1.71.0boost-1.71.0.beta1