2016-12-11 14 views
-2

C++ asioライブラリ(http://think-async.com/Asio/asio-1.10.6/doc/asio/overview/core/allocation.html)のカスタムアロケータ機能を使用しようとしています。私の関数コードはすべて、カスタム割り当て関数void* asio_handler_allocate(std::size_t size, ...)と同様に、名前空間bbにあります。私はADLが私のカスタムバージョンを選択すると予想、何らかの理由でそれが曖昧になり:このADLの解像度があいまいなのはなぜですか?

c:\mysrv\asio\detail\handler_alloc_helpers.hpp(38): error C2668: 'bb::asio_handler_allocate': ambiguous call to overloaded function 
1> c:\mysrv\connection.hpp(16): note: could be 'void *bb::asio_handler_allocate(std::size_t,...)' [found using argument-dependent lookup] 
1> c:\mysrv\asio\impl\handler_alloc_hook.ipp(27): note: or  'void *asio::asio_handler_allocate(std::size_t,...)' 
1> c:\mysrv\asio\detail\handler_alloc_helpers.hpp(38): note: while trying to match the argument list '(std::size_t, bb::Server::do_accept::<lambda_18e060fa7342c1167c1b66e6dfdfd1b2> *)' 

秒1はまた、および/またはこの機能を正しく使用する方法についての一致した理由についてどのような説明をいただければ幸いです

ありがとう

PS私はboost-asioタグを追加しています。なぜなら、それは同じライブラリだと思われますが、異なる名前空間にしかないからです。ここで

http://think-async.com/が単純化された例である私は実際に、スタンドをアローン使用していますC++ 11版はこちらfouind:

#include "asio.hpp" 
#include <memory> 
#include <iostream> 

namespace bb { 
    void* asio_handler_allocate(std::size_t size, ...) { 
     std::cerr << 'H' << ' ' << /**h <<*/ ' ' << size << '\n'; 
     return asio::asio_handler_allocate(size); 
    } 

    class Connection 
     : public std::enable_shared_from_this<Connection> 
    { 
    public: 
     Connection(asio::ip::tcp::socket socket) 
      : socket_(std::move(socket)) 
     { 
     } 

     void start() 
     { 
      do_read(); 
     } 

    private: 
     void do_read() 
     { 
      auto self(shared_from_this()); 
      socket_.async_read_some(asio::buffer(data_), 
       [this, self](std::error_code ec, std::size_t length) 
      { 
       if (!ec) 
       { 
        do_write(length); 
       } 
      }); 
     } 

     void do_write(std::size_t length) 
     { 
      auto self(shared_from_this()); 
      asio::async_write(socket_, asio::buffer(data_, length), 
       [this, self](std::error_code ec, std::size_t /*length*/) 
      { 
       if (!ec) 
       { 
        do_read(); 
       } 
      }); 
     } 

     asio::ip::tcp::socket socket_; 
     std::array<char, 1024> data_; 
    }; 

    class Server 
    { 
    public: 
     Server(asio::io_service& io_service, short port) 
      : acceptor_(io_service, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port)), 
      socket_(io_service) 
     { 
      do_accept(); 
     } 

    private: 
     void do_accept() 
     { 
      acceptor_.async_accept(socket_, 
       [this](std::error_code ec) 
      { 
       if (!ec) 
       { 
        std::make_shared<Connection>(std::move(socket_))->start(); 
       } 

       do_accept(); 
      }); 
     } 

     asio::ip::tcp::acceptor acceptor_; 
     asio::ip::tcp::socket socket_; 
    }; 
} 

int main(int argc, char* argv[]) 
{ 
    try 
    { 
     if (argc != 2) 
     { 
      std::cerr << "Usage: server <port>\n"; 
      return 1; 
     } 

     asio::io_service io_service; 
     bb::Server s(io_service, std::atoi(argv[1])); 
     io_service.run(); 
    } 
    catch (std::exception& e) 
    { 
     std::cerr << "Exception: " << e.what() << "\n"; 
    } 

    return 0; 
} 
+0

Downvoter、説明してください – baruch

+0

あなたの質問を[編集]して[mcve]を提供してください。 –

+0

私は分かりませんが、これは署名が 'asio_handler_allocate(size_t、...)'であり、 'asio_handler_allocate(size_t、std :: function)'のような具体的な型ではないからです。 –

答えて

2
ADLは、単に名前空間のリストに引数の名前空間を追加する名前を見上げべき場所

(これはあまり正確ではありませんが、あなたの質問のためには十分です)。そのネームスペースで自動的に望ましいものを過負荷にすることはありません。同じようにランク付けされた2つの一致が見つかった場合、まだあいまいな状態が発生します。あなたの場合、2つはまったく同じです。

あなたがリンクされASIOドキュメントを読めば、あなたはADLの過負荷を宣言するための正しい方法はHandlerは、ユーザ定義のハンドラタイプです

void* asio_handler_allocate(size_t, Handler); 

であることを知っているだろう。上記の宣言は、Handlerの可能なCV修飾子を持つこともできます。この場合、2つのオーバーロードは、2番目のパラメータが具体的なタイプのものと...のものです。 法律は型付きパラメータと一致します(C++ 11可変型テンプレート引数と混同しないでください)。したがって、あいまいな一致はありません

+0

私は、ADLで見つかったものが優先順位が高くなったと思っていました。それをクリアしていただきありがとうございます。 – baruch

関連する問題