2016-06-26 6 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 
} 

私には2つの可能性があります。リストとベクターです。 list/vectorの値の型がわからない、つまりvector<char>またはvector<int>などが可能なので、ベクトルまたはリストを取得する情報を取得したいだけです。 私はtypeidtype infoに出くわしましたが、本当にそれをやり遂げませんでした。

あなたがそれを達成するためのオーバーロード機能を使用することができます

答えて

3

:テンプレートとして、いずれの場合も、コードはstd::vectorstd::listの両方のためにコンパイルする必要があるため、おそらく理想的な未満である

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 
} 

または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'文を除いて全く同じ関数を持っていれば、すべてを2回持っていない方がいいのではないでしょうか? – 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); 
} 
関連する問題