현재 clang 3.1로 컴파일하면서 boost :: asio로 코드를 작성하려고합니다. 내가 지금처럼 boost::asio::read_until
기능이 전달하려고"후보 템플릿 무시 : 대체 오류 :"컴파일러 오류?
struct tcp_socket_match_condition
{
template <typename TIter>
std::pair<TIter, bool> operator()(TIter begin, TIter end) const
{
auto result(std::find(begin, end, '\n'));
const bool found(result != end);
return std::make_pair(found ? ++result : end, found);
}
};
:
나는 간단한 함수 개체가boost::asio::read_until(socket, stream, match_condition_, error);
컴파일러 오류가 발생 외모를 지적하는 것으로는 할 수 없습니다 올바른 함수 오버로드를 찾으십시오. 이것이 작동하지 않는 이유는 무엇입니까?
전체 클래스 및 컴파일러 오류를 제공했습니다.
In file included from src/network/admin_socket.cpp:1:
In file included from include/bytes42/arthur/network/admin_socket.hpp:4:
include/bytes42/arthur/network/tcp_socket.hpp:95:21: error: no matching function for call to 'read_until'
boost::asio::read_until(socket, stream, match_condition_, error);
^~~~~~~~~~~~~~~~~~~~~~~
src/network/admin_socket.cpp:81:10: note: in instantiation of member function
'bytes42::arthur::network::tcp_socket<bytes42::arthur::network::detail::tcp_socket_match_condition>::listen' requested here
socket_.listen();
^
/usr/local/include/boost/asio/impl/read_until.hpp:47:13: note: candidate function [with SyncReadStream =
boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, Allocator =
std::__1::allocator<char>] not viable: no known conversion from 'bytes42::arthur::network::detail::tcp_socket_match_condition' to 'char' for 3rd
argument;
std::size_t read_until(SyncReadStream& s,
^
/usr/local/include/boost/asio/impl/read_until.hpp:138:13: note: candidate function [with SyncReadStream =
boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, Allocator =
std::__1::allocator<char>] not viable: no known conversion from 'bytes42::arthur::network::detail::tcp_socket_match_condition' to
'const std::string' (aka 'const basic_string<char, char_traits<char>, allocator<char> >') for 3rd argument;
std::size_t read_until(SyncReadStream& s,
^
/usr/local/include/boost/asio/impl/read_until.hpp:203:13: note: candidate function [with SyncReadStream =
boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, Allocator =
std::__1::allocator<char>] not viable: no known conversion from 'bytes42::arthur::network::detail::tcp_socket_match_condition' to
'const boost::regex' (aka 'const basic_regex<char, regex_traits<char> >') for 3rd argument;
std::size_t read_until(SyncReadStream& s,
^
/usr/local/include/boost/asio/impl/read_until.hpp:260:13: note: candidate template ignored: substitution failure [with SyncReadStream =
boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, Allocator =
std::__1::allocator<char>, MatchCondition = bytes42::arthur::network::detail::tcp_socket_match_condition]
std::size_t read_until(SyncReadStream& s,
^
/usr/local/include/boost/asio/impl/read_until.hpp:312:20: note: candidate template ignored: substitution failure [with SyncReadStream =
boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, Allocator =
std::__1::allocator<char>, MatchCondition = bytes42::arthur::network::detail::tcp_socket_match_condition]
inline std::size_t read_until(SyncReadStream& s,
^
/usr/local/include/boost/asio/impl/read_until.hpp:37:20: note: candidate function template not viable: requires 3 arguments, but 4 were provided
inline std::size_t read_until(SyncReadStream& s,
^
/usr/local/include/boost/asio/impl/read_until.hpp:93:20: note: candidate function template not viable: requires 3 arguments, but 4 were provided
inline std::size_t read_until(SyncReadStream& s,
^
/usr/local/include/boost/asio/impl/read_until.hpp:193:20: note: candidate function template not viable: requires 3 arguments, but 4 were provided
inline std::size_t read_until(SyncReadStream& s,
^
1 error generated.
make: *** [build/src/network/admin_socket.o] Error 1
클래스 :
이template <typename TMatchCondition>
class tcp_socket
{
public:
typedef std::function<std::string(const std::string&)> data_callback;
public:
tcp_socket(
const unsigned short port,
TMatchCondition match_condition,
data_callback callback);
void listen();
void stop();
private:
tcp_socket(const tcp_socket&) = delete;
tcp_socket(tcp_socket&&) = delete;
tcp_socket& operator=(const tcp_socket&) = delete;
tcp_socket& operator=(tcp_socket&&) = delete;
private:
const utils::entry_exit entry_exit_;
boost::asio::io_service service_;
boost::asio::ip::tcp::acceptor acceptor_;
TMatchCondition match_condition_;
data_callback callback_;
};
template <typename TMatchCondition>
tcp_socket<TMatchCondition>::tcp_socket(
const unsigned short port,
TMatchCondition match_condition,
data_callback callback)
: entry_exit_("tcp_socket:" + std::to_string(port))
, acceptor_(service_, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
, match_condition_(match_condition)
, callback_(callback) {}
template <typename TMatchCondition>
void tcp_socket<TMatchCondition>::listen()
{
const auto port(acceptor_.local_endpoint().port());
const std::string port_str(std::to_string(port));
while(acceptor_.is_open())
{
boost::system::error_code error;
utils::entry_exit ee("Listening on port " + port_str);
boost::asio::ip::tcp::socket socket(service_);
acceptor_.accept(socket, error);
if(error)
{
if(error != boost::asio::error::bad_descriptor)
{
LOG(ERROR)
<< "An error occured while trying to accept a client connection; error="
<< error.message();
sleep(1); // don't want to flood logs
}
}
else
{
while(socket.is_open())
{
boost::asio::streambuf stream;
boost::asio::read_until(socket, stream, match_condition_, error);
const std::string msg(
(std::istreambuf_iterator<char>(&stream)),
std::istreambuf_iterator<char>());
LOG(INFO) << "Received message: " << msg;
boost::asio::write(
socket,
boost::asio::buffer(callback_(msg)),
error);
if(error)
{
if(error != boost::asio::error::broken_pipe)
{
LOG(ERROR)
<< "Error whilst writing response, closing client connection: "
<< error.message();
}
socket.close();
sleep(1); // don't want to flood logs
}
}
}
}
}
template <typename TMatchCondition>
void tcp_socket<TMatchCondition>::stop()
{
boost::system::error_code error;
acceptor_.close(error);
if(error)
{
LOG(ERROR) << "Error whilst stopping TCP socket; error=" << error.message();
}
}
스펙에서 옵션 값인 것처럼 보입니다 (기본값은 '0'). 필수 사항입니까? – Graeme
일치 조건을 사용하여 과부하를 사용하려면 yes! 이 스펙은 실제로 선택 사항이 아닙니다. 'boost :: is_match_condition :: value'의 결과가'false'로 평가되면 대체 오류가 발생할 수 있기 때문에 오버로드가 오버로드 세트에서 제거됩니다. "선택 사항"이라고 생각하는 것은 네 번째 주장이 무엇인지 판단하는 데 사용되는 마법입니다. –
우수 감사합니다! 'typedef bool result_type'을'tcp_socket_match_condition'에 추가하는 것도 문제를 해결했습니다. – Graeme