2016-11-30 2 views
1

Я пытаюсь распространиться на Can I use decltype (or something similar) for explicit template instantiation without signature duplication? для использования с шаблонами функций-членов, но мне не повезло. Текущие попытки сделать эту работу выглядят так:Использование decltype с макросом для явного инстанцирования функций класса class

// header 
struct my_class 
{ 
    template <typename T> 
    some_type my_func(T val); 
}; 

//source 
template <typename T> 
some_type my_class::my_func(T val) 
{ 
    .... 
} 

// attempt a 
template decltype(my_class::my_func<int>) my_class::my_func<int>; 

// attempt b 
template std::remove_pointer<decltype(&my_class::my_func<int>)>::type my_class::my_func<int>; 

Возможно ли это? Если да, то какие мысли о том, как я могу это сделать?

EDIT:

так кажется, что это требует некоторого обновления компилятора доступно только в звоне или GCC 6.1+. Следующий код, предоставляемый @yakk будет работать на константные методы:

template <class T>                                         
struct pointer_to_member_function{};                                             

template <typename pmf_t> 
using pointer_to_member_signature 
    = typename pointer_to_member_function<pmf_t>::signature; 

template <class ret_t, class class_t, class...args>                                
struct pointer_to_member_function<ret_t(class_t::*)(args...) const>                            
{                                             
    using signature = ret_t(args...) const; 
}; 

Однако следующая модификация компилируется по всей сопзЬ-Несс:

template <class function_t, class class_t>                                
struct pointer_to_member_function<function_t class_t::*>                            
{          
    using signature = function_t;                                    
};    

ответ

1

Я не знаю, если это стандарт соответствует, но она работает в звоне:

template<class Pmf> 
struct pmf_sig{}; 
template<class Pmf> 
using pmf_sig_t=typename pmf_sig<Pmf>::type; 
template<class R, class T, class...Args> 
struct pmf_sig<R(T::*)(Args...)>{ 
    using type=R(Args...); 
}; 

затем const и const& и поддержка &&:

template<class R, class T, class...Args> 
struct pmf_sig<R(T::*)(Args...) const>{ 
    using type=R(Args...) const; 
}; 
template<class R, class T, class...Args> 
struct pmf_sig<R(T::*)(Args...) const&>{ 
    using type=R(Args...) const&; 
}; 
template<class R, class T, class...Args> 
struct pmf_sig<R(T::*)(Args...) const&&>{ 
    using type=R(Args...) const&&; 
}; 
template<class R, class T, class...Args> 
struct pmf_sig<R(T::*)(Args...) &&>{ 
    using type=R(Args...) &&; 
}; 
template<class R, class T, class...Args> 
struct pmf_sig<R(T::*)(Args...) &>{ 
    using type=R(Args...) &; 
}; 

Применение:

template<> pmf_sig_t<decltype(&my_class::my_func<int>)> my_class::my_func<int>; 

Или:

template pmf_sig_t<decltype(&my_class::my_func<int>)> my_class::my_func<int>; 

Идея заключается в том, что my_class:: не является частью сигнатуры в каком-то смысле.

live example.

+0

это работает для функции non-const member, но разваливается, когда const квалифицирован. Мне не повезло со специализацией состязания. мысли? – mgoldman

+0

@mgoldman updated – Yakk

+0

Кажется, что это работает только для clang и gcc 6.1+? В чем недостаток языкового требования для меньших версий gcc? см. https://godbolt.org/g/kWWP7p – mgoldman

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