2016-06-26 3 views
2

컨테이너 유형을 어떻게 확인할 수 있습니까? 나는.컨테이너 유형 확인

template <class Container1> 
void func (Container1 &cont_1) 
{ 
    if (cont_1 is list container) 
    //do stuff 
    if (cont_1 is vector container)  
    //do other stuff 
} 

내가 가질 수있는 두 가지 가능성은 목록과 벡터뿐입니다. list/vector의 값 유형을 모르므로 vector<char> 또는 vector<int> 등이 가능하므로 벡터 또는 목록을 가져 오는 정보 만 얻으려고합니다. 나는 typeidtype info을 보았지만 실제로 끝내지 않았습니다.

답변

3

당신이 달성하기 위해 오버로드 기능을 사용할 수 있습니다 :

template<typename T> 
void func(std::vector<T>& vec) 
{ 
    //Do something with vector 
} 

template<typename T> 
void func(std::list<T>& list) 
{ 
    //Do something with list 
} 

또는 두 경우의 코드가 std::vectorstd::list 모두 컴파일 가능한 일해야하기 때문에, 이상적 아마도 작은 typeid을 사용하는 등 템플릿 은 컴파일 타임에 알려지며, 분기가 std::list에서 실행되지 않을 수도 있지만 컴파일러는 그 시점에서이를 알지 못하므로 std::liststd::vector 연산을 적용하려고하면 컴파일이 실패합니다.

template<template<typename, typename> class C, typename T, typename Alloc> 
void func(C<T, Alloc>& container) 
{ 
    if (typeid(container).hash_code() == typeid(std::vector<T, Alloc>&).hash_code()) 
     ; //Do something with vector 
    else if (typeid(container).hash_code() == typeid(std::list<T, Alloc>&).hash_code()) 
     ; //Do something with list 
} 
+0

오버로드를 사용하지 않는 방법이 있나요? 이 if 문을 제외하고는 완전히 같은 함수가 있다면, 모든 것을 두 번 가지지 않는 것이 좋지 않을까요? – SemtexB

+1

@SemtexB 아마도'if'의 내용이 뭔가를합니다. 따라서 오버로드 된 함수에 넣으십시오. – juanchopanza

+0

@SemtexB 또한 반복 코드를 다른 함수로 추출하여 과부하 또는 역방향으로 호출하여 조건부 항목 만 수행하고 원래 func에서 호출하는 func_if를 생성 할 수 있습니다. –

0

당신은 가변 인자 템플릿을 사용하는 몇 가지 테스트를 작성할 수 있습니다

#include <vector> 

// is_vector 
// ========= 

namespace Detail { 
    template<typename T> 
    struct is_vector_type : std::false_type 
    {}; 

    template<typename ... Types> 
    struct is_vector_type<std::vector<Types...>> : std::true_type 
    {}; 
} 

template<typename T> 
struct is_vector_type : Detail::is_vector_type<typename std::decay<T>::type> 
{}; 

template<typename T> 
constexpr bool is_vector(T&&) { 
    return is_vector_type<T>(); 
} 

// Test 
// ==== 

#include <iostream> 

template <class Container> 
void func (Container &container) 
{ 
    if (is_vector_type<Container>()) { 
    std::cout << "vector\n"; 
    } 
    // or 
    if (is_vector(container)) { 
    std::cout << "vector\n"; 
    } 
    // ... 
} 

int main() { 
    std::vector<int> v; 
    func(v); 
    static_assert(is_vector(v), ""); 
} 
+0

이 방법은 예를 들면. 'cont_1 [i]'벡터의 조건부 섹션에서 컴파일 오류가 발생합니다 ... –

0

오버로드와 접근 방법이 더 나은 물론이지만 완성도 sfinae 메커니즘을 사용하여 다른 하나가있다. C++ 11에서

#include <iostream> 
#include <vector> 
#include <list> 

template <bool V, class T = void> 
struct enable_if { }; 

template <class T> 
struct enable_if<true, T> { 
    typedef T type; 
}; 

struct true_type { 
    static const bool value = true; 
}; 

struct false_type { 
    static const bool value = false; 
}; 

template <class T> 
struct is_list: false_type {}; 

template <class T> 
struct is_list<typename std::list<T> >: true_type { }; 

template <class T> 
struct is_vector: false_type { }; 

template <class T> 
struct is_vector<typename std::vector<T> >: true_type { }; 

template <class C> 
typename enable_if<is_vector<C>::value>::type func(C &c) { 
    // c is a vector here 
    std::cout << "This is a vector" << std::endl; 
} 

template <class C> 
typename enable_if<is_list<C>::value>::type func(C &c) { 
    // c is a list here 
    std::cout << "This is a list" << std::endl; 
} 

int main() { 
    std::vector<int> v; 
    func(v); 
    std::list<int> l; 
    func(l); 
} 

이 조금 더 간단 얻을 것이다 : C 전에 ++ 11 전형적인 코드는 같을 것이다

#include <iostream> 
#include <vector> 
#include <list> 
#include <type_traits> 

template <class T> 
struct is_list: std::false_type {}; 

template <class T> 
struct is_list<typename std::list<T>>: std::true_type { }; 

template <class T> 
struct is_vector: std::false_type { }; 

template <class T> 
struct is_vector<typename std::vector<T>>: std::true_type { }; 

template <class C> 
typename std::enable_if<is_vector<C>::value>::type func(C &c) { 
    // c is a vector here 
    std::cout << "This is a vector" << std::endl; 
} 

template <class C> 
typename std::enable_if<is_list<C>::value>::type func(C &c) { 
    // c is a list here 
    std::cout << "This is a list" << std::endl; 
} 

int main() { 
    std::vector<int> v; 
    func(v); 
    std::list<int> l; 
    func(l); 
}