Specialize C ++ class member function relative to template class

What is my problem:

I have a cc class and I want to specialize a member method of a class relative to another template class (with template argument). Example:

#include <iostream>
#include <string>
#include <complex>

template<class T>
class cc {
    public:

    void foo() ;

    T v ;
};

template<class T> // OK, generic definition of foo()
void cc<T>::foo() {
    std::cout << v << std::endl ;
}

////////////////////////////////////////////////////////////////////
// ERROR! can not accept the the specialization respect to a 
// complex<TT> with a template argument.
template<class TT> 
void cc< std::complex<TT> >::foo() {
    std::cout << "complex t " << v << std::endl ;
}
////////////////////////////////////////////////////////////////////


template<> // OK! specialization respect to a complex<double>
void cc< std::complex<double> >::foo() {
    std::cout << "complex " << v << std::endl ;
}


template<> // OK!
void cc< double >::foo() {
    std::cout << "double: " << v << std::endl ;
}

int main()
{
  cc< std::complex<double> > r ;
  cc<double> r2 ;

  r.foo() ;
  r2.foo() ;
}

In C ++ complex, a template type is used, so I want to write a member function that works with every complex <type> where type is any type of template. Is it possible?

+4
source share
2 answers

you can partially highlight the whole class:

template<class T>
class cc {
public:

    void foo() { std::cout << v << std::endl ; }

    T v ;
};

template <class T>
class cc<std::complex<T>> {
    public:

    void foo() { std::cout << "complex " << v << std::endl ; }

    std::complex<T> v ;
};

or delegating the general method to the “helper” (I show the use of overloads):

template <typename T>
void print(const T&v) { std::cout << v << std::endl ;}

template <typename T>
void print(const std::complex<T>& c) { std::cout << "complex " << c << std::endl; }

template<class T>
class cc {
public:
    void foo() { print(v); }

    T v ;
};
+4
source

, SFINAE. is_complex cc, . std::enable_if ++ 14. ():

#include <iostream>
#include <complex>

template <class T>
struct is_complex : std::false_type {};

template <class T>
struct is_complex<std::complex<T>> : std::true_type {};

template<class T>
class cc {
    public:

    template <class TT = T> // To make SFINAE work
    typename std::enable_if<!is_complex<TT>::value>::type foo() {
        std::cout << "default " << v << std::endl ;
    }

    template <class TT = T> // To make SFINAE work
    typename std::enable_if<is_complex<TT>::value>::type foo() {
        std::cout << "complex t " << v << std::endl ;
    }

    T v ;
};

int main()
{
  cc< std::complex<double> > r ;
  cc<double> r2 ;

  r.foo() ;
  r2.foo() ;
}

Jarod42, print templated member function like this ():

template<class T>
class cc {
    template <typename TT>
    void print(const TT&v) { std::cout << v << std::endl ;}

    template <typename TT>
    void print(const std::complex<TT>& c) { std::cout << "complex " << c << std::endl; }

public:
    void foo() { print(v); }

    T v ;
};
+1

Source: https://habr.com/ru/post/1684462/


All Articles