поясните причину неоднозначности
От: niXman Ниоткуда https://github.com/niXman
Дата: 08.04.13 08:55
Оценка:
приветствую!

есть такой код:
#include <functional>
#include <type_traits>

#include <boost/asio/streambuf.hpp>
#include <boost/system/error_code.hpp>

namespace easynet {

struct shared_buffer {
   std::shared_ptr<char> data;
    size_t size;

    static void deleter(const char* ptr) { delete[] ptr; }
};

namespace detail {

/***************************************************************************/

struct jobitem_base {
   virtual ~jobitem_base() {}
    virtual void invoke() = 0;
};

/***************************************************************************/

template<typename D>
struct ref_val_wrapper {
    using type = typename std::conditional<
        std::is_same<D, shared_buffer>::value
      ,D
      ,typename std::add_lvalue_reference<D>::type
    >::type;
};

template<typename D>
struct handler_sig {
   using type = std::function<
       void( /* start args list */
             const boost::system::error_code& // arg1
            ,typename ref_val_wrapper<D>::type // arg2
            ,std::size_t // arg3
        ) /* end args list */
    >;
};

/***************************************************************************/

template<
     typename D
    ,typename F = typename handler_sig<D>::type
>
jobitem_base* alloc_job(typename ref_val_wrapper<D>::type, F&&) {
    return nullptr;
}

template<
     typename D
   ,typename F = typename handler_sig<D>::type
>
jobitem_base* alloc_job(typename ref_val_wrapper<D>::type, std::size_t, F&&) {
    return nullptr;
}

void free_job(jobitem_base *item) {
    delete item;
}

/***************************************************************************/

} // ns detail
} // ns easynet

/***************************************************************************/

namespace easynet {

template<typename F>
void async_write(shared_buffer buffer, size_t size, F&& handler) {
   auto item = detail::alloc_job(buffer, size, handler); // bad
    //auto item = detail::alloc_job<shared_buffer>(buffer, size, handler); // ok
   ((void)item);
}

} // ns easynet

/***************************************************************************/

int main() {
   easynet::async_write(
       easynet::shared_buffer()
      ,33
      ,[](const boost::system::error_code&, easynet::shared_buffer, size_t){}
   );
   
   std::cout << "ping!" << std::endl;
}

/***************************************************************************/

(хз, как тут впихнуть кат)
получаю такую ошибку:

source.cpp: In instantiation of 'void easynet::async_write(easynet::shared_buffer, size_t, F&&) [with F = main()::__lambda0; size_t = long unsigned int]':
source.cpp:94:4: required from here
source.cpp:80:55: error: no matching function for call to 'alloc_job(easynet::shared_buffer&, size_t&, main()::__lambda0&)'
auto item = detail::alloc_job(buffer, size, handler); // bad
^
source.cpp:80:55: note: candidates are:
source.cpp:53:15: note: template<class D, class F> easynet::detail::jobitem_base* easynet::detail::alloc_job(typename easynet::detail::ref_val_wrapper<D>::type, F&&)
jobitem_base* alloc_job(typename ref_val_wrapper<D>::type, F&&) {
^
source.cpp:53:15: note: template argument deduction/substitution failed:
source.cpp:80:55: note: candidate expects 2 arguments, 3 provided
auto item = detail::alloc_job(buffer, size, handler); // bad
^
source.cpp:61:15: note: template<class D, class F> easynet::detail::jobitem_base* easynet::detail::alloc_job(typename easynet::detail::ref_val_wrapper<D>::type, std::size_t, F&&)
jobitem_base* alloc_job(typename ref_val_wrapper<D>::type, std::size_t, F&&) {
^
source.cpp:61:15: note: template argument deduction/substitution failed:
source.cpp:80:55: note: couldn't deduce template parameter 'D'
auto item = detail::alloc_job(buffer, size, handler); // bad
^

проблема в использовании detail::alloc_job(), которая перегружена для двух и трех аргументов.
в этом примере, я пытаюсь использовать detail::alloc_job() с тремя аргументами. и мне не понятно, почему компилятор видит неоднозначность тут?

спасибо.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: поясните причину неоднозначности
От: uzhas Ниоткуда  
Дата: 08.04.13 09:04
Оценка:
Здравствуйте, niXman, Вы писали:

X>(хз, как тут впихнуть кат)

[cut] бла-бла [\cut]


X>проблема в использовании detail::alloc_job(), которая перегружена для двух и трех аргументов.

X>в этом примере, я пытаюсь использовать detail::alloc_job() с тремя аргументами. и мне не понятно, почему компилятор видит неоднозначность тут?
тут нет неоднозначности, тут есть проблема вывода типа
даже сообщение есть:

source.cpp:61:15: note: template argument deduction/substitution failed:


а вывести тип D не получается здесь:

source.cpp:61:15: note: template<class D, class F> easynet::detail::jobitem_base* easynet::detail::alloc_job(typename easynet::detail::ref_val_wrapper<D>::type, std::size_t, F&&)

вам нужно подсказать тип
Re[2]: поясните причину неоднозначности
От: niXman Ниоткуда https://github.com/niXman
Дата: 08.04.13 09:09
Оценка:
Здравствуйте, uzhas, Вы писали:

U>тут нет неоднозначности, тут есть проблема вывода типа

ну да.

U>вам нужно подсказать тип

понятно.
но почему компилятор неможет вывести тип?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: поясните причину неоднозначности
От: uzhas Ниоткуда  
Дата: 08.04.13 09:10
Оценка:
Здравствуйте, niXman, Вы писали:

X>но почему компилятор неможет вывести тип?


у него такие ограничения
этот вопрос обсуждался, например, здесь: http://www.rsdn.ru/forum/cpp/4561552
Автор: uzhas
Дата: 28.12.11
Re[4]: поясните причину неоднозначности
От: niXman Ниоткуда https://github.com/niXman
Дата: 08.04.13 09:18
Оценка:
Здравствуйте, uzhas, Вы писали:

U>этот вопрос обсуждался, например, здесь: http://www.rsdn.ru/forum/cpp/4561552
Автор: uzhas
Дата: 28.12.11

спасибо, читаю. (но что-то пока появляется только больше вопросов %) )
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: поясните причину неоднозначности
От: rus blood Россия  
Дата: 08.04.13 11:47
Оценка: 12 (1)
Здравствуйте, niXman, Вы писали:

X>но почему компилятор неможет вывести тип?


Вот пример std::forward из MSVC:
template<class _Ty> inline
    _Ty&& forward(typename identity<_Ty>::type& _Arg)
    {    
    return ((_Ty&&)_Arg);
    }


Тут identity<_Ty> не несет никакой смысловой нагрузки, и нужен только для того, чтобы заблокировать вывод типа и заставить явно указать тип аргумента шаблона.
Если тут не использовать identity<_Ty>, и компилер сам бы выводил тип из аргумента, то forward во всех случаях (если тип явно не указан) работал бы как std::move, т.е. неправильно.
Имею скафандр — готов путешествовать!
Re[4]: поясните причину неоднозначности
От: niXman Ниоткуда https://github.com/niXman
Дата: 09.04.13 07:52
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Тут identity<_Ty> не несет никакой смысловой нагрузки, и нужен только для того, чтобы заблокировать вывод типа и заставить явно указать тип аргумента шаблона.

RB>Если тут не использовать identity<_Ty>, и компилер сам бы выводил тип из аргумента, то forward во всех случаях (если тип явно не указан) работал бы как std::move, т.е. неправильно.
понял.
вопрос закрыт. всем спасибо.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.