일반 유형으로 특정 유형의 STL 컨테이너

특정 유형의 컨테이너를 std::string매개 변수로 사용하는 함수를 만들 수있는 방법이 있습니까?

void foo(const std::container<std::string> &cont)
{
   for(std::string val: cont) {
      std::cout << val << std::endl;
   }
}

모든 유형의 stl 컨테이너에 대해 입력으로 호출합니까? 위처럼?

std::set<std::string> strset;
std::vector<std::string> strvec;
std::list<std::string> strlist;

foo(strset);
foo(strvec);
foo(strlist);



답변

컨테이너 유형에 대한 템플리트 템플리트 매개 변수 를 사용 foo하여 함수 템플리트를 작성할 수 있습니다 .

예 :

template<template<typename...> typename C>
void foo(const C<std::string> &cont)
{
   for(std::string val: cont) {
      std::cout << val << std::endl;
   }
}

라이브


답변

foo다른 경우 에 과부하 를 원하느냐에 따라

// Doesn't participate in overload resolution when not applicable
template<typename Container, typename = std::enable_if_t<std::is_same_v<typename Container::value_type, std::string>>>
void foo(const Container &cont) {
   for(std::string val: cont) {
      std::cout << val << std::endl;
   }
}

// simpler
template<typename Container>
void foo(const Container &cont) {
   static_assert(std::is_same_v<typename Container::value_type, std::string>, "Container must contain std::string")
   for(std::string val: cont) {
      std::cout << val << std::endl;
   }
}

다음 std::is_same과 같은 다른 테스트를 사용 std::is_convertible하여 허용 할 수 있습니다.

std::vector<char *> c_strings;
foo(c_strings);


답변

대신 반복자를 사용하는 것이 좋습니다. 중간 결과는 다음과 같습니다

template<typename Iter>
void foo(Iter begin, Iter end) {
  using T = decltype(*begin);
  std::for_each(begin, end, [] (cons T & t) {
    std::out << t << '\n';
  }
}

이제 호출 가능한 템플릿을 사용하십시오.

template<typename Iter, typename Callable>
void foo(Iter begin, Iter end, Callable & c) {
  std::for_each(begin, end, c);
}

우리는 STL이 이미 제공하는 것을 사용하는 법을 배웠습니다.


답변

@songyuanyao의 답변에 덧붙여서 다음과 같이 더 일반화 할 수 있다고 생각합니다.

template<template<typename...> typename C, typename ... D>
void foo(const C<D...> &cont)
{
   for(const auto& val: cont) {
      std::cout << val << std::endl;
   }
}


답변