【问题标题】:template template return type from member function来自成员函数的模板模板返回类型
【发布时间】:2014-01-20 04:19:44
【问题描述】:

如何从成员函数返回任何整数容器?在下面的代码中,我尝试了两个测试类之间的任何排列,但似乎没有使用 g++-4.8.2 编译:

#include "vector"

struct test {
    template<class Container> Container<int> ret() {
        return Container<int>();
    }
};

struct test {
    template<
        template<class Int> class Container,
        class Int
    > typename Container<Int> ret() {
        return Container<Int>();
    }
};

int main() {
    std::vector<int> v = test().ret<std::vector<int> >();
    return 0;
}

理想情况下,程序应该是 c++03 并且仅当 int 是包含的类型时才编译。在其他情况下向用户打印一个可读错误也很好,但我想这需要 boost 或 std static_assert()。谢谢!

编辑 1

不幸的是,2 模板参数版本仅适用于少数标准容器,注释掉的会导致编译错误,因为它们需要不同的模板参数:

struct test {
    template<
        template<class, class> class Container
    > Container<int, std::allocator<int> > ret() {
        return Container<int, std::allocator<int> >();
    }
};

int main() {
    std::vector<int> v = test().ret<std::vector>();
    std::list<int> l = test().ret<std::list>();
    //std::set<int> se = test().ret<std::set>();
    std::deque<int> d = test().ret<std::deque>();
    //std::stack<int> st = test().ret<std::stack>();
    //std::queue<int> q = test().ret<std::queue>();
    //std::priority_queue<int> p = test().ret<std::priority_queue>();
    return 0;
}

但以下 c++11 版本似乎适用于每个容器:

struct test {
    template<
        template<class, class...> class Container,
        class... Container_Params
    > Container<int, Container_Params... > ret() {
        return Container<int, Container_Params... >();
    }
};

int main() {
    auto v = test().ret<std::vector>();
    auto l = test().ret<std::list>();
    auto se = test().ret<std::set>();
    auto d = test().ret<std::deque>();
    auto st = test().ret<std::stack>();
    auto q = test().ret<std::queue>();
    auto p = test().ret<std::priority_queue>();
    auto us = test().ret<boost::unordered_set>();
    return 0;
}

【问题讨论】:

    标签: c++ template-templates


    【解决方案1】:
    test().ret<std::vector, int>();
    

    我认为是正确的

    而且.. 你的test 结构是两个??

    【讨论】:

    • std::vector 不是类型
    【解决方案2】:
    template<bool _Test, class _Ty = void>
    struct enable_if
    {};
    
    template<class _Ty>
    struct enable_if<true, _Ty>
    { typedef _Ty type; };
    
    template < typename _Type >
    struct is_int_container { static const bool value = false; };
    
    template < typename _Alloc >
    struct is_int_container < std::vector < int, _Alloc > > { static const bool value = true; };
    
    template < typename _Alloc >
    struct is_int_container < std::list < int, _Alloc > > { static const bool value = true; };
    
    template < typename _Equal, typename _Alloc >
    struct is_int_container < std::set < int, _Equal, _Alloc > > { static const bool value = true; };
    
    // Add any required container support
    
    struct test 
    {
        template< typename _Type> 
        typename enable_if < is_int_container <_Type> ::value, _Type > ::type
        ret() 
        {
            return _Type();
        }
    };
    
    int main(int agrc, char *argv[])
    {
        test test_;
    
        test_.ret<std::vector<int>>();
        test_.ret<std::set<int>>();
        test_.ret<std::vector<double>>();  // <- compilator error
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      您的一个问题是std::vector 采用 2 个模板参数(T 和一个分配器)

      因此,如果您想学习模板类,以下内容可能会对您有所帮助:

      struct test {
          template<template<typename, typename> class Container>
          Container<int, std::allocator<int>> ret() {
              return Container<int, std::allocator<int>>();
          }
      };
      
      int main(int argc, char *argv[])
      {
          std::vector<int> v = test().ret<std::vector>();
          return 0;
      }
      

      如果您使用类,另一种方法是将 SFINAE 用作:

      template <typename Container, typename T>
      struct is_container_of :
          std::conditional<std::is_same<
                  typename std::decay<decltype(*std::begin(std::declval<Container>()))>::type,
                  T>::value,
                  std::true_type, std::false_type>::type {};
      
      struct test {
          template<class Container>
          typename std::enable_if<is_container_of<Container, int>::value, Container>::type
          ret() {
              return Container();
          }
      };
      
      int main(int argc, char *argv[])
      {
          auto v = test().ret<std::vector<int>>();
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-02-11
        • 1970-01-01
        • 1970-01-01
        • 2019-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多