1

I have a class template defined as follow

template<typename T>
class A
{
  T t_;
  // void f();
};

My question is how to add the f() method only if the type T is integer without compilation error.

int main()
{
  A<int> a; // OK
  A<string> b; // OK
}

Example :

#include <type_traits>
#include <new>
#include <iostream>
#include <string>



template <typename T>
struct Foo
{
    T t;
    template <typename..., typename U = T>
    std::enable_if_t<std::is_same_v<T, int>> say_hello() { std::cout << "Hello"; }
};


int main()
{
    Foo<int>();
    Foo<double>();
}
Error   C2938   'std::enable_if_t<false,void>' : Failed to specialize alias template

Thank you.

Andrew
  • 47
  • 5

1 Answers1

1

You can enable specific functions using type_traits and SFINAE:

#include <iostream>
#include <string>
#include <type_traits>

template<typename T>
class A
{
public:
    template<typename U = T, std::enable_if_t<std::is_integral_v<U>, int> = 0>
    void f() {
        std::cout << "int " << t_ << '\n';
    }
private:
    T t_;
};


int main() {
    A<int> a;
    a.f();

    A<std::string> s;
    // s.f(); //  error: no member named 'f' in 'A<std::__cxx11::basic_string<char> >'
}

If you have many integer specific functions you can put them in a class of its own and inherit that class only if T is integral.

#include <iostream>
#include <string>
#include <type_traits>

template<typename Atype>
class int_functions {
public:
    Atype* This() { return static_cast<Atype*>(this); }

    void f() {
        std::cout << "int " << This()->t_ << '\n';
    }
};

template<typename Atype>
class non_int_functions {
};

template<typename T>
class A : public std::conditional_t<std::is_integral_v<T>, int_functions<A<T>>,
                                                           non_int_functions<A<T>>>
{
    friend std::conditional_t<std::is_integral_v<T>, int_functions<A<T>>,
                                                     non_int_functions<A<T>>>;
public:
private:
    T t_;
};
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • I don't have a special functions to integer type.its just one function. I try to avoid a copy paste of the code – Andrew Mar 20 '20 at 05:02
  • 1
    @Roger Ok, added a simpler solution for that case. There wouldn't be any copy/pasting using my first suggestion though. – Ted Lyngmo Mar 20 '20 at 05:03