2015-03-20 3 views
2

Я пытаюсь создать две перегруженные функции, которая принимает обработчик в качестве аргумента:Перегрузка функций C++ с подобными аргументами

template <typename Handler> 
void foo (Handler h); 

Первой перегрузка должна быть вызвана, если обработчик принимает повышение :: ASIO: : yield_context в качестве параметра,

template <class Handler> 
void foo (Handler h, 
    enable_if_t<is_same<result_of_t<Handler (yield_context)>, void>::value>* = 0); 

и второй один должен быть вызван, если обработчик принимает повышение :: функции в качестве параметра.

using func_type = boost::function<void(int,int)>; 

template <typename Handler> 
void foo (Handler h, 
    enable_if_t<is_same<result_of_t<Handler (func_type)>, void>::value>* = 0); 

К сожалению, это не работает:

main.cpp:22:3: error: call to 'foo' is ambiguous 
    foo ([] (func_type f) {}); 
    ^~~ 
main.cpp:11:6: note: candidate function [with Handler = (lambda at main.cpp:22:8)] 
void foo (Handler h, 
    ^
main.cpp:16:6: note: candidate function [with Handler = (lambda at main.cpp:22:8)] 
void foo (Handler h, 
    ^
1 error generated. 

Интересно, но код прекрасно работает с станд :: функции:

using func_type = boost::function<void (int,int)>; 

Насколько я понимаю, что это потому, что импульс :: функция имеет чрезмерные перегрузки для всех возможных вызывающих операторов, и это сбивает result_of проверок.

В любом случае, возможно ли создать «foo» перегрузки, которые могли бы «отличить» между обработчиками, использующими yield_context и обработчиками, использующими boost :: function в качестве параметров?

Coliru код: http://coliru.stacked-crooked.com/a/18344cd1b8364466

ответ

1

Стандартная библиотека, кажется, принял "прозвище" аргумент подход:

unique_lock<mutex> lk(std::defer_lock, mx); 

или

std::pair<Foo, Foo> p1(t, t); 
std::pair<Foo, Foo> p2(std::piecewise_construct, t, t); 

или

std::async(std::launch::deferred, foo, argument1); 
std::async(std::launch::async, foo, argument1); 

и т.д.

Узор что

struct defer_lock_t final { }; // for exposition 
constexpr defer_lock_t defer_lock; 

Эти «клички» имеют «уникальные» обнаруживаемые типы, которые гарантированно не начертанию/кабриолет и т.д. с фактическими типами аргументов.

Смежные вопросы