2

引数として標準コンテナー (リスト、スタック、ベクターなど) のいずれかを取ることができる関数を作成しようとしています。コンテナ内の型も知りたいです。これが私が試したことです。

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

template<class data_type, template<class> class container_type>
void type(container_type<data_type>& _container){
        std::cout<<typeid(container_type).name()<<std::endl;
}


int main(){

    std::list<int> list_t;
    std::vector<int> vector_t;
    type(list_t);
    type(vector_t);
}

container_typeこの関数内の once の型は常に_Container_base_aux_alloc_empty、標準コンテナの基本クラスであると思います。

ここで何が起こっているのですか?

この関数が正しい型を返すようにするにはどうすればよいですか?

4

4 に答える 4

2

の typeid は役に立ちcontainer_typeません。これは単なるテンプレート クラスであり、テンプレート クラスは実際の型ではなく、インスタンス化後にのみになるためです。したがって、実際に必要なのはdata_type、値の型のcontainer_type<data_type>の型と、インスタンス化されたコンテナーの型の の型です。もちろん、さらに良いのはcontainer_type<data_type>::value_type、値の型として取ることです。

ほとんどのコンテナーは複数のテンプレート パラメーターを取ることに注意してください。

template <template <typename...> class Container, typename ...Args>
void print_type(const Container<Args...> &)
{
  typedef typename Container<Args...>::value_type value_type;
  print(typeid(Container<Args...>).name());
  print(typeid(value_type).name());
}
于 2011-08-21T18:58:27.637 に答える
1

typeid() の出力はあまり信用できません。type_info::Name が一意の識別子を返すことは保証されていません。そのため、関数内の型が期待どおりである可能性が非常に高くなります。

型の何らかの名前を取得する最善の方法は、次のようなマクロを使用することです。

template<class data_type, template<class> class container_type>
void type_helper(container_type<data_type>& _container, const char* charStr){
        std::cout<< charStr << std::endl
}

#define type(container) type_helper(container, #container)
于 2011-08-21T18:47:36.023 に答える
1

コンテナのタイプはすでにあります。ですdata_type。このように使用するだけです。疑問がある場合typename container_type::value_typeは、コンテナのテンプレート引数の typedef である which を使用することもできます。

型の使用については以上です。型を返すことは、C++ ではまったく異なることであり、一般にテンプレート メタプログラミングの一部と見なされます。

このかなり無意味なスニペットは、value_type何らかのタイプからを抽出しTます。

template<typename T>
struct inner_type {
  typedef T::value_type value_type;
};

ただし、 をvalue_type直接使用して、この難読化を回避することもできます。

于 2011-08-21T18:54:19.243 に答える
1

誰かがアロケーターなどを交換するとすぐに、あなたのコードは機能しません。C++03 の場合は任意の T を使用::value_typeし、C++0x の場合は型推定を使用する必要があります。

また、.name()有用なものを返すように定義されていません。どんな状況でも。実装は、すべてのタイプに対して「har har sucker!この言語機能を使用して頑張ってください」を返し、準拠している可能性があります。

于 2011-08-21T18:54:58.313 に答える