No matching function for call to 'bind'

Le problème exposé dans ce sujet a été résolu.

Salut ca zeste ?
Je me suis récemment attaqué à boost.asio. Donc j'ai fais un petit client server en tcp
voila le résultat auquel je suis arrivé.

le serveur:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

using namespace boost::asio;

void read(ip::tcp::socket &socket){
    std::cout <<"                   ";


    std::array<char, 10000>buf;     //une idée pour remplacé ce tableau en un std::string ?  
    boost::system::error_code ec;
    size_t size = socket.read_some(buffer(buf),ec);

    if(ec !=0){
        std::cout << ec.message();
    }else{
        std::cout.write(buf.data(),size);
        std::cout <<"\n";
    }

}



void write(ip::tcp::socket& socket){
    std::string msg;
    getline(std::cin, msg);
    socket.send(buffer(msg));
}

int main()
{
    while (true)
    {
        try
        {
            io_service ios;

            ip::tcp::endpoint endpoint(ip::tcp::v4(),7777);

            ip::tcp::acceptor acceptor(ios,endpoint);





            ip::tcp::socket socket(ios);
            acceptor.accept(socket);
            while (socket.is_open()) {
                write(socket);
                read(socket);


            }



        }

        catch (boost::system::error_code& ec)
        {
            if(ec.value() != 0)
            {
                std::cerr<<"error code: "<<ec.value()<<"\n\n"<<"error msg: "<<ec.message();
            }
        }
    }
    return EXIT_SUCCESS;
}

le client

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <thread>

using namespace boost::asio;

void read(ip::tcp::socket& socket){

    std::cout <<"                   ";
    std::array<char, 10000>buf;
    boost::system::error_code ec;
    size_t size = socket.read_some(buffer(buf),ec);

    if(ec !=0){
        std::cout << ec.message();
    }else{
        std::cout.write(buf.data(),size);
        std::cout <<"\n";
    }
}


void write(ip::tcp::socket& socket){
    std::string msg;
    getline(std::cin, msg);
    socket.send(buffer(msg));
}

int main()
{
    try{

        io_service ios;
        unsigned int port = 7777;
        std::string ip {"192.168.1.112"};

        ip::tcp::endpoint ep(ip::address::from_string(ip), port);
        ip::tcp::socket socket(ios,ep.protocol());
        socket.connect(ep);     
        while (socket.is_open()) {

            read(socket);
            write(socket);

        }
    }

    catch(boost::system::error_code& ec){
        if (ec.value() != 0) {
            std::cerr <<"error during running... \n#########################################"<<std::endl
            <<"error code: "<<ec.value()<<std::endl<<"error message: "<<ec.message()<<std::endl;
        }
    }

    return EXIT_SUCCESS;
}

Donc comme vous pouvez le voir, j'ai quelques restrictions: chaque personne doit parler l'une après l'autre. Impossible que la même personne n'écrivent deux messages consécutifs donc.

j'ai alors pensé à plusieurs solutions: mettre la fonction write dans un autre threads indépendant afin que la fonction getline(std::cin,msg); ne bloque pas l'affichage de nouveaux messages.

J'ai aussi pensé à utiliser un deadline_timer avec une attente asynchrone qui appelle les fonctions read et write toutes les 0.1 seconde
mon problème se pose ici:

t_read.async_wait(boost::bind( read,socket));
ou
std::thread thread{boost::bind(write,socket)};

j'ai l'erreur: No matching function for call to 'bind'

PS:je vais améliorer mon code, le faire orienté objet, ce code est plus pour tester les fonctionnalités de Boost.Asio.
PSS: si vous avez des remarques sur n'importe quel aspect du code je serai heureux de les entendre.

merci ;-)

+0 -0

Salut, je ne peut pas t'aider pour le reste, mes connaissance en résaux sont vague et celles en boost sont nul mais d'après cppreference bind se trouve dans le header functional, tu as juste a l'inclure et tu n'auras plus l'erreur No matching function for call to 'bind' :)

Je crois que ma réponse est inutile, je viens de remarquer que tu utilises boost::bind -_- je fais quelques recherches plus approfondis pour voir si je peux t'aider

J'ai trouvé cette page sur la doc de boost qui est pas super et je pense juste que tu as oublié un argument le _1, _2, _3 etc…

J'espère avoir résolu ton problème, j'ai fais tous mon possible :)

+0 -0

Salut, tout d'abord merci de ta réponse.
j'utilise en effet boost::bind mais je sais pas si std::bind est plus approprié ou a un comportement différent et comme dans l'exemple ici ils montrent l'utilisation avec boost::bind, j'ai fais pareil.
J'ai suivis ton idée:std::thread thread{boost::bind(write, _1)(socket)}; mais j'ai toujours la même erreur. J'ai fait différent teste et si l'argument de la fonction est un type du style entier, float etc ca fonctionne. Ca marche même avec std::string. j'ai l'impression que le problème vient de l'argument.

Je ne sais pas pourquoi mais des fois ils mettent un & devant la fonction:
std::thread thread{boost::bind(&write, _1)(socket)};

+0 -0

Normalement std::bind et boost::bind ont le même comportement, il me semble que c'est pour changer l'ordre des argument d'une fonction.

Et les & c'est pour le passage par référence.

+0 -0

Salut.

Pour la sémantique de std/boost::bind, cela permet de réaliser la curryfication d'une fonction, et les deux versions ont à très peu de chose près la même interface. Néanmoins, on préfère généralement utiliser une lambda.

1
2
3
4
5
6
7
8
9
void f(int a, int b);

// bind
auto f_bind = std::bind(f, 2, std::placeholders::_1);
f_bind(3) // Appelle f(2, 3)

//lambda
auto f_lambda = [](int a){f(a, 5);};
f_lambda(6) // Appelle f(6, 5)
+1 -0

Merci, je comprends mieux son utilité.
Mais malgré ton aide, la création du thread ne compile pas. J'ai donc regardé quelques morceaux de code et dans le livre C++ Concurrency in Action il y a ce code:
void f(int i,std::string const& s);
std::thread t(f,3,”hello”);

j'ai donc fait ceci:std::thread thread(write, socket); mais ca ne marche toujours pas. Je ne comprends pas. Tous les testes que je fais avec std::bind ou sans et avec ou sans paramètre fonctionne. j'ai l'impression que le problème vient de la socket que je passe en paramètre

+0 -0

En effet je ne savais pas qu'elles avaient ce comportement, le problème vient de la. Ma fonction fonctionne sans le thread, et dans la doc de std::thread il est dit que le thread copi les valeurs. Il faut donc que j'envoie une référence au constructeur de thread pour qu'il n'y ait pas de copie c'est bien ça ?

std::thread thread( boost::bind(&read, std::ref(socket))); Ceci ne fonctionne pas. Je vais faire d'autre recherche demain, je fatigue pour le moment Encore merci pour vos réponses

+0 -0

Bon je ne trouve vraiment pas. Je dois mal comprendre utilisation de bind. Toutes les solutions que j'ai essayées ont échouée.
J'ai essayé en passant un objet de type shared_ptr<boost::agio::ip::tcp::socket> ca n'a pas fonctionné, j'ai aussi tenter avec un ip::tcp::socket*socket = new ip::tcp::socket(ios); et en envoyant socket en paramètre de bind (j'ai bien changé la fonction pour qu'elle prenne un pointeur et non plus une référence. Mais bind me dit toujours que l'appelle ne correspond a aucune fonction de bind connue No matching function for call to 'bind'

Je sais pas trop quoi essayer d'autre

+0 -0

Pense à donner l'erreur complète lorsque tu rencontre un problème de compilation. Lorsque le compilateur te dit no matching function […], il te donne aussi la liste des possibilités essayées. Quelle est cette liste ?

Par contre, dans ton exemple std::thread thread( boost::bind(&read, std::ref(socket)));, read est une fonction. L'expression read renvoie donc déjà un pointeur sur fonction, et l'ajout de & est redondant. C'est nécessaire uniquement lors de la construction d'un pointeur sur fonction membre (auto member_ptr = &MyClass::MyFunction).

Pour le reste, il faudrait l'erreur complète et le morceau de code complet correspondant.

+0 -0

j'ai l'erreur no matching[…] et dans le menu déroulant dessous j'ai:

chemin/usr/include/c++/v1/functional:2221:1: Candidate template ignored: couldn't infer template argument '_Fp'
et
/chemin/usr/include/c++/v1/functional:2230:1: Candidate template ignored: couldn't infer template argument '_Rp'

chemin est le chemin, je l'ai remplacé pour éviter une dizaine de lignes qui, je pense, ne sont pas très utiles

PS: j'utilise Xcode comme IDE et clang comme compilateur.

J'ai aussi compiler avec g++ comme cela g++-5 -I/usr/local/Cellar/boost/1.60.0_1/include -L/usr/local/Cellar/boost/1.60.0_1/lib -lboost_system -std=c++14 -Wall main.cpp -o final

et voici ce que j'ai eu:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
main.cpp: In function 'int main()':
main.cpp:68:55: error: no matching function for call to 'bind(<unresolved overloaded function type>, std::reference_wrapper<boost::asio::basic_stream_socket<boost::asio::ip::tcp> >)'
    std::thread thread(std::bind(read, std::ref(socket)));
                                                       ^
In file included from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/memory:79:0,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/addressof.hpp:21,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/handler_alloc_helpers.hpp:19,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/bind_handler.hpp:19,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/wrapped_handler.hpp:18,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/io_service.hpp:24,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/basic_io_object.hpp:19,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/basic_socket.hpp:20,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/basic_datagram_socket.hpp:20,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio.hpp:21,
                 from main.cpp:12:
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:1462:5: note: candidate: template<class _Func, class ... _BoundArgs> typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...)
     bind(_Func&& __f, _BoundArgs&&... __args)
     ^
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:1462:5: note:   template argument deduction/substitution failed:
main.cpp:68:55: note:   couldn't deduce template parameter '_Func'
    std::thread thread(std::bind(read, std::ref(socket)));
                                                       ^
In file included from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/memory:79:0,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/addressof.hpp:21,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/handler_alloc_helpers.hpp:19,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/bind_handler.hpp:19,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/wrapped_handler.hpp:18,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/io_service.hpp:24,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/basic_io_object.hpp:19,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/basic_socket.hpp:20,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/basic_datagram_socket.hpp:20,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio.hpp:21,
                 from main.cpp:12:
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:1490:5: note: candidate: template<class _Result, class _Func, class ... _BoundArgs> typename std::_Bindres_helper<_Result, _Func, _BoundArgs>::type std::bind(_Func&&, _BoundArgs&& ...)
     bind(_Func&& __f, _BoundArgs&&... __args)
     ^
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:1490:5: note:   template argument deduction/substitution failed:
main.cpp:68:55: note:   couldn't deduce template parameter '_Result'
    std::thread thread(std::bind(read, std::ref(socket)));
                                                       ^
In file included from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/throw_error.hpp:19:0,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/impl/posix_tss_ptr.ipp:23,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/posix_tss_ptr.hpp:76,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/tss_ptr.hpp:27,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/call_stack.hpp:20,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/impl/handler_alloc_hook.ipp:19,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/handler_alloc_hook.hpp:80,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/handler_alloc_helpers.hpp:21,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/bind_handler.hpp:19,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/wrapped_handler.hpp:18,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/io_service.hpp:24,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/basic_io_object.hpp:19,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/basic_socket.hpp:20,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/basic_datagram_socket.hpp:20,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio.hpp:21,
                 from main.cpp:12:
/usr/local/Cellar/boost/1.60.0_1/include/boost/system/error_code.hpp: At global scope:
/usr/local/Cellar/boost/1.60.0_1/include/boost/system/error_code.hpp:221:36: warning: 'boost::system::posix_category' defined but not used [-Wunused-variable]
     static const error_category &  posix_category = generic_category();
                                    ^
/usr/local/Cellar/boost/1.60.0_1/include/boost/system/error_code.hpp:222:36: warning: 'boost::system::errno_ecat' defined but not used [-Wunused-variable]
     static const error_category &  errno_ecat     = generic_category();
                                    ^
/usr/local/Cellar/boost/1.60.0_1/include/boost/system/error_code.hpp:223:36: warning: 'boost::system::native_ecat' defined but not used [-Wunused-variable]
     static const error_category &  native_ecat    = system_category();
                                    ^
In file included from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/impl/posix_tss_ptr.ipp:24:0,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/posix_tss_ptr.hpp:76,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/tss_ptr.hpp:27,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/call_stack.hpp:20,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/impl/handler_alloc_hook.ipp:19,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/handler_alloc_hook.hpp:80,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/handler_alloc_helpers.hpp:21,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/bind_handler.hpp:19,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/detail/wrapped_handler.hpp:18,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/io_service.hpp:24,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/basic_io_object.hpp:19,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/basic_socket.hpp:20,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio/basic_datagram_socket.hpp:20,
                 from /usr/local/Cellar/boost/1.60.0_1/include/boost/asio.hpp:21,
                 from main.cpp:12:
/usr/local/Cellar/boost/1.60.0_1/include/boost/asio/error.hpp:258:45: warning: 'boost::asio::error::system_category' defined but not used [-Wunused-variable]
 static const boost::system::error_category& system_category
                                             ^
/usr/local/Cellar/boost/1.60.0_1/include/boost/asio/error.hpp:260:45: warning: 'boost::asio::error::netdb_category' defined but not used [-Wunused-variable]
 static const boost::system::error_category& netdb_category
                                             ^
/usr/local/Cellar/boost/1.60.0_1/include/boost/asio/error.hpp:262:45: warning: 'boost::asio::error::addrinfo_category' defined but not used [-Wunused-variable]
 static const boost::system::error_category& addrinfo_category
                                             ^
/usr/local/Cellar/boost/1.60.0_1/include/boost/asio/error.hpp:264:45: warning: 'boost::asio::error::misc_category' defined but not used [-Wunused-variable]
 static const boost::system::error_category& misc_category

Et voici le code qui provoque ces erreurs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <functional>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <thread>
#include <memory>
#include <array>

using namespace boost::asio;

void read(ip::tcp::socket& socket){
  boost::system::error_code ec;
  while ( ec==0 ) {
      std::cout <<"                   ";
      
      
      std::array<char, 10000>buf;
      
      size_t size = socket.read_some(buffer(buf),ec);
      
      if(ec !=0){
          std::cout << ec.message();
      }else{
          std::cout.write(buf.data(),size);
          std::cout <<"\n";
      }
  }
  
  
}



void write(ip::tcp::socket& socket){
  
  std::string msg;
  getline(std::cin, msg);
  socket.send(buffer(msg));
}

int main()
{
  
  while (true)
  {
      try
      {
          io_service ios;
          
          ip::tcp::endpoint endpoint(ip::tcp::v4(),7777);
          
          ip::tcp::acceptor acceptor(ios,endpoint);
          ip::tcp::socket socket(ios);
          
          
          acceptor.accept(socket);
          
          
          std::thread thread(std::bind(read, std::ref(socket)));
          thread.detach();
          
          std::string msg;
          boost::system::error_code error;
          while (socket.is_open()) {
              write(socket);
              
              
          }
          
          
      }
      
      catch (boost::system::error_code& ec)
      {
          if(ec.value() != 0)
          {
              std::cerr<<"error code: "<<ec.value()<<"\n\n"<<"error msg: "<<ec.message();
          }
      }
  }
  return EXIT_SUCCESS;
}

Merci encore pour toutes l'aide ;-)
PS: j'ai mis les erreurs dans un bloc de code sinon c'était illisible

+0 -0

C'est visiblement un conflit de nom. J'ai testé en changeant le nom de la fonction read et ça fonctionne. Il y a probablement une autre fonction nommée read déclarée dans les fichiers d'entête inclus, et du coup ça coince parce que le compilateur ne sait pas laquelle choisir.

+0 -0

C'est visiblement un conflit de nom. J'ai testé en changeant le nom de la fonction read et ça fonctionne. Il y a probablement une autre fonction nommée read déclarée dans les fichiers d'entête inclus, et du coup ça coince parce que le compilateur ne sait pas laquelle choisir.

Praetonus

oui sans doute dans boost::asio du coup le using namespace boost::asio vire le seul moyen de les différencier.

D’ailleurs ça me fais poser cette question, est-ce qu'il n'y a pas d'équivalent à ce code python en c++ : import math as m ?

+0 -0

tralala c'est bien ça, on m'avait bien dit que les using namespace c'était diabolique.
Un grand merci à vous, je met le sujet en résolu et vous fait plein de bisous

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte