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

C++ 在vc+中使用模板限制类型+;,c++,templates,visual-c++,C++,Templates,Visual C++,就我的理解而言,我只想为下面的类限制两种类型int和string,就像在带有extenses的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 buff

就我的理解而言,我只想为下面的类限制两种类型int和string,就像在带有extenses的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);
};
模板
typename std::enable_if::type
类交换端口
{
公众:
void bubbleSort(T buffer[],int s);
无效打印(T缓冲区[],整数s);
void bubbleSort(常量向量和向量向量);
};
但如果我像下面这样实例化

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

我收到了上面的交换错误。端口未定义。问题出在哪里?

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
模板
类交换端口
{
静态断言(std::is_same::value | | std::is_same::value,“ExchangeSort需要int或string”);
公众:
//其余的和以前一样


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

这里有另一种方法,可以进一步增加专业化:

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

}
#包括
#包括
#包括
//
//步骤1:polyfill缺少c++17概念
//
名称空间notstd{
模板结构析取:std::false_type{};
模板结构析取:B1{};
模板
结构析取
:std::conditional_t{};
}
//
//步骤2:创建一个测试以查看类型是否在列表中
//
名称空间详细信息{
模板
结构是:notstd::disconction{};
}
模板
static constexpr auto IsOneOf=detail::是::value的其中一个;
//
//步骤3:声明默认专业化,但不定义它
//
模板
结构交换端口;
//
//第四步:定义我们想要的专业
//
模板
类交换端口
{
公众:
void bubbleSort(T buffer[],int s);
无效打印(T缓冲区[],整数s);
void bubbleSort(const std::vector&vec);
};
//
//试验
//
int main()
{
自动esi=ExchangeSort();
auto ess=ExchangeSort();
//不会编译
//自动esd=ExchangeSort();
}