专门针对模板类的c ++类成员函数

时间:2017-08-25 12:29:38

标签: c++ c++11 templates

这是我的问题:

我有一个cc类,我想专门针对另一个模板类(带有模板参数)的类成员方法。 一个例子:

#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() ;
}

在c ++中,complex是一个模板类型,所以我想写一个适用于每个复杂的成员函数&lt;类型&gt;其中type是任何模板类型。 有可能吗?

2 个答案:

答案 0 :(得分:4)

你可以局部专注于整个班级:

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 ;
};

或将通用方法委托给&#34;帮助者&#34; (我展示了重载的使用):

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 ;
};

答案 1 :(得分:1)

以下是使用SFINAE的解决方案。如果需要,谓词is_complex可以成为类cc的嵌套类型。使用C ++ 14,std::enable_if语法更好一些。这里是(online):

#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() ;
}

<强>委派

受到answer Jarod42的启发,我们可以将print函数实现为模板化成员函数(online):

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 ;
};