当前位置:  开发笔记 > 编程语言 > 正文

限制模板功能

如何解决《限制模板功能》经验,为你挑选了3个好方法。

我在http://codepad.org/ko8vVCDF上编写了一个使用模板函数的示例程序.

如何将模板功能限制为仅使用数字?(int,double等)

#include 
#include 

using namespace std;

    template 
T sum(vector& a)
{
    T result = 0;
    int size = a.size();
    for(int i = 0; i < size; i++)
    {
        result += a[i];
    }

    return result;
}

int main()
{
    vector int_values;
    int_values.push_back(2);
    int_values.push_back(3);
    cout << "Integer: " << sum(int_values) << endl;

    vector double_values;
    double_values.push_back(1.5);
    double_values.push_back(2.1);
    cout << "Double: " << sum(double_values);

    return 0;
}

Leon Timmerm.. 20

这可以通过使用SFINAE来实现,并且通过使用Boost或C++ 11中的帮助程序变得更容易

促进:

#include 
#include 
#include 

template 
    typename boost::enable_if::type, T>::type 
        sum(const std::vector& vec)
{
  typedef typename std::vector::size_type size_type;
  T result;
  size_type size = vec.size();
  for(size_type i = 0; i < size; i++)
  {
    result += vec[i];
  }

  return result;
}

C++ 11:

#include 
#include 

template 
    typename std::enable_if::value, T>::type 
        sum(const std::vector& vec)
{
  T result;
  for (auto item : vec)
    result += item;
  return result;
}


Jeff Hillman.. 19

你可以这样做:

template 
class NumbersOnly
{
private:
    void ValidateType( int    &i ) const {}
    void ValidateType( long   &l ) const {}
    void ValidateType( double &d ) const {}
    void ValidateType( float  &f ) const {}

public:
    NumbersOnly()
    {
       T valid;
       ValidateType( valid );
    };
};

如果您尝试创建没有ValidateType重载的NumbersOnly,您将收到错误:

NumbersOnly justFine;
NumbersOnly noDeal;

我简单地认为这是错误的(抱歉),但方法签名中的&是至关重要的 - 它会阻止实例化的类型只能转换为int.所以char,unsigned int和一个重载operator int()的类都按预期被禁止. (4认同)


Lou Franco.. 18

限制模板的唯一方法是使它使用所需类型的东西,而其他类型则没有.

因此,使用int构造,使用+和+ =,调用复制构造函数等.

任何具有所有这些功能的类型都可以与你的函数一起使用 - 所以,如果我创建一个具有这些功能的新类型,你的函数就可以使用它 - 这很棒,不是吗?

如果要对其进行更多限制,请使用仅为所需类型定义的更多函数.

实现此目的的另一种方法是创建一个特征模板 - 就像这样

template
SumTraits
{
public:
  const static bool canUseSum = false;
}

然后将它专门用于你想要的类:

template<>
class SumTraits
{
  public:
    const static bool canUseSum = true;
};

然后在你的代码中,你可以写

if (!SumTraits::canUseSum) {
   // throw something here
}

编辑:如评论中所述,您可以使用BOOST_STATIC_ASSERT使其成为编译时检查而不是运行时检查



1> Leon Timmerm..:

这可以通过使用SFINAE来实现,并且通过使用Boost或C++ 11中的帮助程序变得更容易

促进:

#include 
#include 
#include 

template 
    typename boost::enable_if::type, T>::type 
        sum(const std::vector& vec)
{
  typedef typename std::vector::size_type size_type;
  T result;
  size_type size = vec.size();
  for(size_type i = 0; i < size; i++)
  {
    result += vec[i];
  }

  return result;
}

C++ 11:

#include 
#include 

template 
    typename std::enable_if::value, T>::type 
        sum(const std::vector& vec)
{
  T result;
  for (auto item : vec)
    result += item;
  return result;
}



2> Jeff Hillman..:

你可以这样做:

template 
class NumbersOnly
{
private:
    void ValidateType( int    &i ) const {}
    void ValidateType( long   &l ) const {}
    void ValidateType( double &d ) const {}
    void ValidateType( float  &f ) const {}

public:
    NumbersOnly()
    {
       T valid;
       ValidateType( valid );
    };
};

如果您尝试创建没有ValidateType重载的NumbersOnly,您将收到错误:

NumbersOnly justFine;
NumbersOnly noDeal;


我简单地认为这是错误的(抱歉),但方法签名中的&是至关重要的 - 它会阻止实例化的类型只能转换为int.所以char,unsigned int和一个重载operator int()的类都按预期被禁止.

3> Lou Franco..:

限制模板的唯一方法是使它使用所需类型的东西,而其他类型则没有.

因此,使用int构造,使用+和+ =,调用复制构造函数等.

任何具有所有这些功能的类型都可以与你的函数一起使用 - 所以,如果我创建一个具有这些功能的新类型,你的函数就可以使用它 - 这很棒,不是吗?

如果要对其进行更多限制,请使用仅为所需类型定义的更多函数.

实现此目的的另一种方法是创建一个特征模板 - 就像这样

template
SumTraits
{
public:
  const static bool canUseSum = false;
}

然后将它专门用于你想要的类:

template<>
class SumTraits
{
  public:
    const static bool canUseSum = true;
};

然后在你的代码中,你可以写

if (!SumTraits::canUseSum) {
   // throw something here
}

编辑:如评论中所述,您可以使用BOOST_STATIC_ASSERT使其成为编译时检查而不是运行时检查


您还可以使用BOOST_STATIC_ASSERT在编译时强制执行该条件.
推荐阅读
保佑欣疼你的芯疼
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有