繁体   English   中英

C ++-专门用于模板类的成员函数

[英]C++ - Specialize member function for Template Class

我有一个代表数学向量的类模板:

template<class Value_T, unsigned int N>
class VectorT
{
public:

    void Normalize()
    {
        // normalize only double/float vectors here
    }

private:
    // elements in the vector
    value_type elements[N];     

    // the number of elements
    static const size_type size = N;
};

我想对整数类型的向量进行特殊处理,因为在这种类型的向量上不可能进行向量归一化。 因此,我需要一个单独的(可能是专门化的)规范化方法,该方法取决于VectorT类模板的模板参数Value_T。

我试图以不同的方式使用模板专业化,但是没有使其正常工作。 我是否必须使Normalize函数本身成为模板函数? 目前,这只是正常的成员方法。

您可以使用标签分配技术解决此问题:

#include <iostream>
#include <type_traits>

template<class Value_T, unsigned int N>
class VectorT
{
public:
    void Normalize()
    {
        using tag = std::integral_constant<bool
                                         , std::is_same<Value_T, double>::value
                                           || std::is_same<Value_T, float>::value>;  

        // normalize only double/float vectors here
        Normalize(tag());
    }

private:
    void Normalize(std::true_type)
    {
        std::cout << "Normalizing" << std::endl;
    }

    void Normalize(std::false_type)
    {
        std::cout << "Not normalizing" << std::endl;
    }

    // elements in the vector
    Value_T elements[N];     

    // the number of elements
    static const std::size_t size = N;
};

演示

似乎您要禁止对除浮点以外的其他类型进行Normalize ,因此您可以使用static_assert获得良好的错误消息:

template<class Value_T, unsigned int N>
class VectorT
{
public:

    void Normalize()
    {
        static_assert(std::is_floating_point<Value_T>::value, "Normalize available only for floating point");
        // normalize only double/float vectors here
    }

// Other stuff

};

您也可以使用std :: enable_if <>

#include <iostream>
#include <type_traits>

template<class Value_T>
class VectorT
{
public:
    template<class T = Value_T>
    typename std::enable_if<std::is_integral<T>::value, void>::type
    Normalize()
    {
        std::cout << "Not normalizing" << std::endl;
    }

    template<class T = Value_T>
    typename std::enable_if<!std::is_integral<T>::value, void>::type
    Normalize()
    {
         std::cout << "Normalizing" << std::endl;
    }
};

int main()
{
    VectorT<int> vint;
    VectorT<double> vdouble;

    vint.Normalize();
    vdouble.Normalize();

    return 0;
}

演示

是的,您可以独立地专门化模板类的特定成员函数。 但是,功能模板(包括成员功能模板)不允许部分专业化 功能模板仅支持显式专业化 您的情况下的显式专业化如下所示

// Header file

template<class Value_T, unsigned int N>
class VectorT
{
public:

  void Normalize()
  {
      // normalize only double/float vectors here
  }
  ...
};

// Declare an explicit specialization for <int, 5>
template <> void VectorT<int, 5>::Normalize();

接着

// Implementation file

// Define the explicit specialization for <int, 5>
template <> void VectorT<int, 5>::Normalize()
{
   ...
}

但是,显然不需要显式初始化,因为您只想“固定”类型并保持大小灵活,即需要部分专业化。 可以使用C ++ 11的std::enable_if功能(如其他答案所示)以及C ++ 98的一些基本技巧来完成。

当然,如果您的类相对较轻,也就是说,除了Normalize之外,它没有太多通用代码,您可以简单地对整个类进行部分专业化处理。 这将需要更多的输入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM