0

첫 번째 질문에 stackoverflow :) 저는 C++에 비교적 새로운 템플릿을 사용한 적이 없으므로 어리석은 짓을하는 경우 용서해주십시오. 템플릿 함수를 목록을 통해 빗질하고 일반적인 형식의 지정된 요소를 확인합니다. 그런 식으로 문자열이나 int를 찾는 지 여부를 지정할 수 있습니다.템플릿 함수는 "호출에 대한 일치 함수가 없습니다"오류를 제공합니다

template <class T> 
bool inList(T match, std::string list) 
{ 
    int listlen = sizeof(list); 
    for (int i = 0; i <= listlen; i++) { 
     if (list[i] == match) return true; 
     else continue; 
    } 
    return false; 
}; 

이것은 나의 전화 inList()입니다.

error: no matching function for call to 'inList(const char [5], std::vector<std::basic_string<char> >&)' 

내가 뭐하는 거지 : 나는 다음과 같은 오류 때렸다하고, 컴파일시 내 실망과 혼란을

if (inList<string>("test", testvec)) 
    cout << "success!"; 
else cout << "fail :("; 

: testvec는 "테스트"를 포함한 몇 가지 요소를 문자열 벡터입니다 틀리게? :(

나는 템플릿 정의가 글로벌 네임 스페이스에 있음을 언급. (내 템플릿이 작동되는지 확인하는 간단한 테스트 프로그램, 그리고 그것은 분명히하지 않습니다 :()

답변

4
무시 [편집]

std :: vector에서 std :: string으로 변환 할 수있는 방법이 없기 때문에 컬렉션 개념에 대한 추상화가 필요합니다.

이렇게하면 사람들이 컬렉션을 전달할 수 있습니다. 컬렉션의 '개념'에 맞는 한 배열, 벡터, 문자열,리스트, 큐 등을 사용할 수 있습니다 (여기에 C++ 1x에는 개념이 있습니다. !). 그들은 심지어 자신의 사내에서 사용할 수 있습니다. 특별히 최적화 된 컬렉션 유형. 그것은 템플릿의 아름다움입니다.

template<class elem_t, class list_t> 
bool in_list(const elem_t& elem, const list_t& list) { 
    for (const auto& i : list) { 
     if (elem == i) { 
     return true; 
     } 
    } 
    return false; 
} 

편집 : : C++ 사용 11

(표준 수집, 원시적 배열, 사용자 정의 형식 작동)이 템플릿으로 표준 : initializer_list 추론 할 수있는 비 표준 확장이다 인수, 그래서 명시 적으로 우선 제공 :

template<class elem_t> 
bool in_list(const elem_t& elem, std::initializer_list<elem_t> list) { 
    for (const auto& i : list) { 
     if (elem == i) { 
     return true; 
     } 
    } 
    return false; 
} 

이 버전을, 당신은 그것을 좋아 호출 할 수 있습니다 :

int main() { 
    std::vector<int> a = {1, 2, 3, 4, 5}; 
    std::cout << in_list(3, a) << std::endl; 
    std::string b = "asdfg"; 
    std::cout << in_list('d', b) << std::endl; 
    std::cout << in_list('d', "asdfg") << std::endl; 
    std::cout << in_list(3, {1, 2, 3, 4, 5}) << std::endl; 
    return 0; 
} 

그리고 여전히 C++ 98을 사용하는 사용자에게는 문자열과 벡터 및 일부 사용자 정의 형식 모두에서 작동합니다. 그래도 원시 배열에서는 작동하지 않습니다. 당신이 STL 스타일 갈 수

template<class elem_t, class list_t> 
bool in_list_98(const elem_t& elem, const list_t& list) { 
    list_t::const_iterator end = list.end(); //prevent recomputation of end each iteration 
    for (list_t::const_iterator i = list.begin(); i < end; ++i) { 
     if (elem == *i) { 
     return true; 
     } 
    } 
    return false; 
} 

또는 : 나는 실수를 한 경우

template<class elem_t, class iterator_t> 
bool in_list_stl(const elem_t& elem, iterator_t begin, iterator_t end) { 
    for (iterator_t i = begin; i < end; ++i) { 
     if (elem == *i) { 
     return true; 
     } 
    } 
    return false; 
} 
//call like std::string s = "asdf"; in_list_stl('s', s.begin(), s.end()); 

가, 미안, 내가 지금 실행 내 컴파일러를 필요는 없습니다 ...

+0

다양성이 좋은 . 짧은 대답은 문자열로 변환 할 것으로 예상되는 문자열 벡터 대신 문자열을 전달하는 것입니다. 이 목적을 위해 기술적으로'includes()'또는'find()'가 있습니다.) 자신을 단단한 하나 쓸 필요가 없습니다. – chris

+0

나는 내 문제를 해결했다고 언급 한 이후로 내 페이지를 새로 고치기 전에 chris가 내 질문에 대한 자신의 의견을 삭제했다고 생각합니다. 나는 매우 어리 석다. 'std :: vector '을 문자 그대로 사용할 수 있는지 모르므로'std :: string'을'inList()'의 인수로 사용했습니다. 벡터를 사용했기 때문에'std :: string'을 사용해야한다고 생각했지만, 지금은 바보 같이 돌아보고 있습니다.** 답장을 보내 주셔서 감사합니다. 응답은 나중에 참조 할 때 유용합니다. Robert :) ** – ZeroKnight

+0

std :: includes 또는 std :: find를 사용하는 경우 end()에 대해 테스트하는 것을 잊지 마십시오. in_list (a, b) == [] (auto & a, const auto & b) {return std :: find (b.begin(), b.end(), a)! = b.end(); } - 나는 람다를 추상적 코드 라기보다는 실제 코드가 아니라는 것을 의미한다. 나는 우리가 다형성 람다를 가지고 있지 않다는 것을 안다. 그것은 우리가 지금 haskell로 떠나야 만하는 것입니다. –