模板容器的c++模板专用化

cyvaqqii  于 2022-12-15  发布在  其他
关注(0)|答案(1)|浏览(216)

我会做的就是...

template < template <typename ... > typename __Container, typename ... __Args >
ostream& operator<<(ostream& os, __Container<__Args ...> const& rhs){
  stringstream ss;
  int i = 0;
  for (const auto& it : rhs) 
    ss << "idx[" << i << "] " << it << "\n";
  return os << ss.str();
}

/// 
/// ... and something template specialization code
/// 

int main (){
  std::vector<int> vec_data = { ... };
  std::cout << vec_data << std::endl; 

  std::deque<int> dq_data = { ... };
  std::cout << dq_data << std::endl; 

  std::map<std::string, double> map_data = { {}, {}, {}, ... };
  std::cout << map_data << std::endl; 

  return 0;
}

字符串
在这个例子中,deque和vector不是问题,但是当我试图专门化std::map时,我把它转储了。有没有可能方法来做到这一点?

bnl4lu3b

bnl4lu3b1#

函数模板不能部分专用化,但可以重载:

template <typename ...P>
std::ostream &operator<<(std::ostream &os, const std::map<P...> &map)

但这不是最好的主意,因为您还必须专门针对std::multimapstd::unordered_[multi]map,以及将来遇到的任何非标准容器。
相反,你可以创建一个函数来打印单个元素,并为std::pair(Map的元素类型)重载它,然后从你的操作符中调用它。
代码还有更多问题:

  • 运算符应该只在ADL可以找到的地方重载,否则你将不能从某些地方调用它们(从定义任何operator<<的任何名称空间;或者从运算符上面定义的模板函数)。

因为这里唯一合适的名称空间是std,并且不允许在那里添加声明,所以首先不应该创建这样的操作符,而是编写一个函数。

  • 包含__或以_[A-Z]开头的标识符被保留,不要使用它们。
  • operator<<应接受任何basic_ostream<...>以支持宽流。
  • stringstream应该是ostringstream,或者完全删除(直接打印到ostream)。

相关问题