【问题标题】:restricting the types using templates in vc++在 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 未定义的错误。有什么问题?

【问题讨论】:

    标签: c++ templates visual-c++


    【解决方案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>();
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-09
        • 2011-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多