1

У меня есть класс и шаблон классаФункция перегрузки шаблон головоломка

class promise; 

template <class... Ts> 
class typed_promise; 

Я намерен разработать программу произнесения, чтобы бросить между ними

template <class... Ts> 
typed_promise<Ts...> promise_cast(promise x); 

template <class... Ts> 
promise promise_cast(typed_promise<Ts...> x); 

Таким образом, вы можете сделать следующее ввергнуть

promise pms; 
typed_promise<int, int> typed_pms; 
auto typed_pms2 = promise_cast<int, int>(pms); 
auto pms2 = promise_cast(typed_pms); 

Я также хочу поддерживать использование как

auto typed_pms2 = promise_cast<typed_promise<int, int>>(pms); 

что эквивалентно

auto typed_pms2 = promise_cast<int, int>(pms); 

Поскольку C++ не допускает частичную функцию специализации шаблона, можно добиться того, что я хочу? Если возможно, как мне это сделать?

+0

«не разрешает» неправильно. «Не поддерживает напрямую» больше нравится. Но здесь я не вижу * технической * проблемы, у вас есть две разные перегрузки. Просто изменяя чисто декларации на определения, [код работает] (http://coliru.stacked-crooked.com/a/c9c7c7415e98d6a4). –

+0

Проголосовало за то, чтобы закрыть как отсутствующий пример проблемы. –

+1

@ Cheersandhth.-Alf Это сделает 'typed_promise >'. –

ответ

2

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

template<class... Ts> 
struct promise_cast_impl { 
    static typed_promise<Ts...> do_cast(promise) { 
     // do stuff 
    } 
}; 

template<class... Ts> 
struct promise_cast_impl<typed_promise<Ts...>> { 
    static typed_promise<Ts...> do_cast(promise p){ 
     return promise_cast_impl<Ts...>::do_cast(std::move(p)); 
    } 
}; 

template<class... Ts> 
auto promise_cast(promise x) 
    -> decltype(promise_cast_impl<Ts...>::do_cast(std::move(x))){ 
    return promise_cast_impl<Ts...>::do_cast(std::move(x)); 
} 

Если вы не используете Ts... в другом месте, вы можете упростить это немного, написав metafunction, что просто вычисляет тип возвращаемого из Ts....

+0

Да. Это решает мою проблему :-) Просто передайте вызов функции шаблону класса, который я могу частично специализировать. – Lingxi

3

Когда перегрузка становится сложной, вы должны рассмотреть альтернативу перегрузке вообще.

Дайте функции другим именам, возможно add_promise_type и erase_promise_type. Тогда не требуется «частичная специализация».

template <class... Ts> 
typed_promise<Ts...> add_promise_type(promise x); 

template <class... Ts> 
promise erase_promise_type(typed_promise<Ts...> x); 

Это часто заманчиво подражать типажи, но это минное поле XY problems. Вы будете более счастливы с более простым решением, которое на самом деле более специфично для этой задачи.

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