От: | 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;
}
/***************************************************************************/
проблема в использовании detail::alloc_job(), которая перегружена для двух и трех аргументов.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
^