2012-11-21 3 views
3

현재 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(); 
     } 
    }         

답변

2

난 당신이 전체 코드를 게시하지만 문제는 경기 조건이 될 것으로 보인다 생각하지 않는다 : 당신은 당신의 tcp_socket_match_condition가 일치 조건이 boost::is_match_condition를 사용하여 지정 했습니까?

+0

스펙에서 옵션 값인 것처럼 보입니다 (기본값은 '0'). 필수 사항입니까? – Graeme

+1

일치 조건을 사용하여 과부하를 사용하려면 yes! 이 스펙은 실제로 선택 사항이 아닙니다. 'boost :: is_match_condition :: value'의 결과가'false'로 평가되면 대체 오류가 발생할 수 있기 때문에 오버로드가 오버로드 세트에서 제거됩니다. "선택 사항"이라고 생각하는 것은 네 번째 주장이 무엇인지 판단하는 데 사용되는 마법입니다. –

+0

우수 감사합니다! 'typedef bool result_type'을'tcp_socket_match_condition'에 추가하는 것도 문제를 해결했습니다. – Graeme

1

; 그래서 clang이 (여기) 도움이되고 있습니다.

개의 개의 특수화가 있으며 read_until 개의 특수화가 있으며 어떤 것도 작동하지 않는다고 알려줍니다.

처음 세 개는 세 번째 매개 변수에 char, char 및 std :: string을 사용합니다. 그것은 작동하지 않습니다.

마지막 세 개의 매개 변수가 있습니다. 네 개를 전달하는 것입니다. 그것들도 싫어한다.

이렇게하면 두 명이 중간에 남습니다. 어떤 이유로 든 TMatchCondition이 대체 오류를 생성하고 있습니다.

Dietmar가 방금 지적한 것처럼 boost::is_match_condition<TMatchCondition>::value이 맞는지 확인해야합니다. 정확하지 않은 경우 작동하지 않기 때문에 확인해야합니다.