Я пытаюсь лучше понять std::enable_if
в C ++ 11 и пытаюсь написать минимальный пример: класс A
с функцией-членом void foo()
, которая имеет разные реализации на основе типа T
из шаблона класса.
Приведенный ниже код дает желаемый результат, но я еще не полностью его понимаю. Почему работает версия V2
, а V1
нет? Почему требуется "избыточный" тип U
?
#include <iostream>
#include <type_traits>
template <typename T>
class A {
public:
A(T x) : a_(x) {}
// Enable this function if T == int
/* V1 */ // template < typename std::enable_if<std::is_same<T,int>::value,int>::type = 0>
/* V2 */ template <typename U=T, typename std::enable_if<std::is_same<U,int>::value,int>::type = 0>
void foo() { std::cout << "\nINT: " << a_ << "\n"; }
// Enable this function if T == double
template <typename U=T, typename std::enable_if<std::is_same<U,double>::value,int>::type = 0>
void foo() { std::cout << "\nDOUBLE: " << a_ << "\n"; }
private:
T a_;
};
int main() {
A<int> aInt(1); aInt.foo();
A<double> aDouble(3.14); aDouble.foo();
return 0;
}
Есть ли лучший способ достичь желаемого результата, т.е. иметь разные реализации функции void foo()
на основе параметра шаблона класса?
enable_if
. Простая перегрузка решит ваш случай.enable_if
в основном полезен для выведенного параметра шаблона. - person Kerrek SB   schedule 16.01.2017std::enable_if
подходит для отделения выведенных типов с плавающей запятой, скажем, от целочисленных типов. Два конкретных типа, подобных этому, лучше подходят для перегрузки. - person WhozCraig   schedule 16.01.2017void A<int>::foo() {}
иvoid A<double>::foo() {}
? Я хотел бы, чтобы окончательный код содержал только те версии функции, которые требуются (то есть без функцииA<double>::foo()
, если такая функция никогда не вызывается) - person mattu   schedule 16.01.2017typename U=T
заставляет этот пример работать, но не без этого. Кто-нибудь объяснит это? - person A.S.H   schedule 16.01.2017