Вы также должны использовать enable_if
в объявлении, как и определение.
template <typename T>
class Base{
public:
template <typename U>
typename std::enable_if<!std::is_same<U, bool>::value, U>::type Compute(U a, U b);
};
LIVE
На самом деле, clang отклоняет ваш текущий код, как я ожидал, потому что объявление и определение не совпадают.
ошибка: внешнее определение 'Compute' не соответствует ни одному объявлению в 'Base'
РЕДАКТИРОВАТЬ (для вашего добавленного вопроса)
Вы можете
template <OpType T>
class Base{
public:
template <typename U, OpType X = T>
typename std::enable_if<
(X == OpType::INT && !std::is_same<U, bool>::value)
||
(X == OpType::BITWISE && std::is_same<U, bool>::value), U
>::type
Compute(U a, U b);
};
using AddOperation = Base<OpType::INT>;
template<>
template<typename U, OpType X>
typename std::enable_if<
(X == OpType::INT && !std::is_same<U, bool>::value)
||
(X == OpType::BITWISE && std::is_same<U, bool>::value), U
>::type
AddOperation::Compute(U a, U b){
std::cout << a << "," << b << std::endl;
return a + b;
}
using AndOperation = Base<OpType::BITWISE>;
template<>
template<typename U, OpType X>
typename std::enable_if<
(X == OpType::INT && !std::is_same<U, bool>::value)
||
(X == OpType::BITWISE && std::is_same<U, bool>::value), U
>::type
AndOperation::Compute(U a, U b){
return a & b;
}
затем
std::cout << b.Compute<int>(10, 2) << std::endl; // fine
std::cout << a.Compute<bool>(true, true) << std::endl; // fine
std::cout << b.Compute<bool>(true, true) << std::endl; // error, no matching function
std::cout << a.Compute<int>(10, 2) << std::endl; // error, no matching function
LIVE
Другой подход - специализация шаблона класса , для разделения реализации OpType::INT
и OpType::BITWISE
.