Чтобы сократить количество повторных использований определенного типа std::enable_if
, используемого в классе для переключения присутствия функции на основе типа шаблона класса, соответствующего определенному типу, я использовал объявление шаблона псевдонима. Минимальный пример моей общей настройки выглядит следующим образом:
#include <type_traits>
class A final {};
template<typename T>
class B final {
public:
template<typename U, typename V>
using check = std::enable_if_t<std::is_same_v<U, V>>;
template<typename U = T>
check<U, A> foo();
};
template<typename T>
template<typename U>
typename B<T>::template check<U, A> B<T>::foo() {
}
int main() {
B<A> b;
b.foo();
}
Хотя в Clang 7.0.0 это работает нормально, как видно здесь, Visual Studio 15.5.7 с другой стороны (с использованием /std:c++17
) не удается скомпилировать со следующим сообщением об ошибке:
main.cpp(17): error C2244: 'B<T>::foo': unable to match function definition to an existing declaration
main.cpp(17): note: see declaration of 'B<T>::foo'
main.cpp(17): note: definition
main.cpp(17): note: 'B<T>::check<U,A> B<T>::foo(void)'
main.cpp(17): note: existing declarations
main.cpp(17): note: 'enable_if<_Test,_Ty>::type B<T>::foo(void)'
with
[
_Ty=void
]
Это проблема с реализацией компилятором Visual Studio различных функций, необходимых для правильной работы SFINAE, или что-то не так с использованием шаблона псевдонима таким образом? Следует также отметить, что полная замена псевдонима полным типом std::enable_if
действительно решает эту проблему, но мне более любопытно, почему это так, и есть ли способ избежать дублирования кода.