在 vc++ 中使用模板限制类型

Posted

技术标签:

【中文标题】在 vc++ 中使用模板限制类型【英文标题】:restricting the types using templates in vc++ 【发布时间】:2017-03-25 06:52:54 【问题描述】:

就我的理解而言,我只想为以下类限制 2 种类型 int 和 string,就像在 java 模板定义中使用扩展一样。

template<typename T>
typename std::enable_if<std::is_same<T,int>::value || std::is_same<T,string>::value>::type
class ExchangeSort

public:
    void bubbleSort(T buffer[], int s);
    void print(T buffer[], int s);
    void bubbleSort(const vector<T>& vec);
;

但是如果我像下面这样实例化

ExchangeSort<int>* sortArray = new ExchangeSort<int>;

我收到上述行 ExchangeSort 未定义的错误。有什么问题?

【问题讨论】:

【参考方案1】:

SFINAE 可用于有条件地禁用函数重载或模板特化。尝试使用它来禁用类模板是没有意义的,因为类模板不能被重载。最好使用静态断言:

template<typename T>
class ExchangeSort

  static_assert(std::is_same<T,int>::value || std::is_same<T,string>::value, "ExchangeSort requires int or string");
public:
  // The rest as before

至于您遇到的错误,代码没有语法意义。 enable_if 只能出现在需要类型的地方。对于函数,它通常用于包装返回类型,在这种情况下,它在语法上与您编写的内容相似。但是对于类,template 和类定义之间没有类型。

【讨论】:

【参考方案2】:

这是另一种可以增加更多专业化的方法:

#include <type_traits>
#include <vector>
#include <string>

//
// Step 1 : polyfill missing c++17 concepts
//
namespace notstd 

    template<class...> struct disjunction : std::false_type  ;
    template<class B1> struct disjunction<B1> : B1  ;
    template<class B1, class... Bn>
    struct disjunction<B1, Bn...>
            : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>>   ;


//
// Step 2 : create a test to see if a type is in a list
//
namespace detail 

    template<class T, class...Us>
    struct is_one_of : notstd::disjunction< std::is_same<T, Us>... > ;


template<class T, class...Us>
static constexpr auto IsOneOf = detail::is_one_of<T, Us...>::value;


//
// Step 3 : declare the default specialisation, but don't define it
//

template<class T, typename Enable = void>
struct ExchangeSort;

//
// Step 4 : define the specialisations we want
//
template<typename T>
class ExchangeSort<T, std::enable_if_t<IsOneOf<T, int, std::string>>>

public:
    void bubbleSort(T buffer[], int s);
    void print(T buffer[], int s);
    void bubbleSort(const std::vector<T>& vec);
;


//
// Test
//

int main()


    auto esi = ExchangeSort<int>();
    auto ess = ExchangeSort<std::string>();

// won't compile    
//    auto esd = ExchangeSort<double>();


【讨论】:

以上是关于在 vc++ 中使用模板限制类型的主要内容,如果未能解决你的问题,请参考以下文章

C++模板非类型模板参数

视频下集:1小时学会!用C++模板快速编写Windows窗口图形界面程序,不用MFC

限制指针类型模板参数和覆盖模板基类的虚拟方法

在 VC++2008 Express 中查找不依赖于模板参数的名称。它是一个错误吗?

VC++ 6.0当中,CString和string这两种类型有啥区别?

C++17 模板类初始化的折叠表达式的限制类型