C++ C++;根据其模板定义类成员类型

C++ C++;根据其模板定义类成员类型,c++,metaprogramming,template-meta-programming,C++,Metaprogramming,Template Meta Programming,在我们的代码中,我们有以下类: template<class A, class B> class myClass { typedef std::list<Object<A,B>> MyList; typedef std::map<A, typename mList::iterator> MyMap MyList mList; MyMap mMap; } 模板 类myClass { typedef std::lis

在我们的代码中,我们有以下类:

template<class A, class B>
class myClass
{
    typedef std::list<Object<A,B>> MyList;
    typedef std::map<A, typename mList::iterator> MyMap

    MyList mList;
    MyMap mMap;
}
模板
类myClass
{
typedef std::list MyList;
typedef std::map MyMap
糜棱岩;
MyMap-mMap;
}
类是元编程的,它可以是字符串、int等等。 我想更改代码,以便在类A是“元字符串”的情况下使用映射,否则将使用无序的_映射

我尝试添加更多元编程,但尚未成功:

template< class A, class B>
struct MapType // default
{
    typedef std::list<Object<A,B>> MyList;
    typedef std::unordered_map<A,B> MyMap;
}

//TODO struct with templated A (string) to use std::map

template<class A, class B>
class myClass
{
    ???? // if A ~ String define myMap to MAP . otherwise unordered

    MyList mList;
    MyMap mMap;
}
模板
结构映射类型//默认值
{
typedef std::list MyList;
typedef std::无序映射MyMap;
}
//带有模板(字符串)的TODO结构以使用std::map
模板
类myClass
{
??//如果~字符串将myMap定义为MAP,则为无序
糜棱岩;
MyMap-mMap;
}
对于使用不同地图类型的任何其他建议也将不胜感激


感谢一个简单的解决方案是使用
std::conditional
检查
A
是否与您的“元字符串”类相同(出于演示目的,我选择了
std::string
):

模板
类myClass
{
std::列表mList;
std::条件mMap;
};

另一种可能是使用部分专业化:

template<class A, class B>
class myClass
{
    std::list<Object<A,B>> mList;
    std::unordered_map<A,B> mMap;
};

template<class B>
class myClass<std::string,B>
{
    std::list<Object<std::string,B>> mList;
    std::map<std::string,B> mMap;
};
模板
类myClass
{
std::列表mList;
std::无序地图mMap;
};
模板
类myClass
{
std::列表mList;
std::map-mMap;
};
使用特征:

例如,如果元字符串的意思是
std::string
。或者你可以根据自己的需要修改它

另外,我认为您指的是
typename MyList::iterator
,而不是
typename mList::iterator

假设“元字符串”的类型为
foo
(我刚刚虚构的名称,因为您没有指定“元字符串”是什么,您只需执行以下操作即可

template< class A, class B>
struct MapType // default
{
    typedef std::list<Object<A,B>> MyList;
    typedef std::unordered_map<A,B> MyMap;

    MyList mList;
    MyMap mMap;
};


template<class B>
struct MapType<foo, B>
{
     typedef std::list<Object<foo, B>> MyList;
     typedef std::map<foo,B> MyMap;

     MyList mList;
     MyMap mMap;
};
模板
结构映射类型//默认值
{
typedef std::list MyList;
typedef std::无序映射MyMap;
糜棱岩;
MyMap-mMap;
};
模板
结构映射类型
{
typedef std::list MyList;
typedef std::map MyMap;
糜棱岩;
MyMap-mMap;
};

使用部分专门化(用于可能没有std::conditional的C++11之前版本),您不需要专门化整个类(这可能是复制大量方法的一大负担),但您可以专门化映射类型:

template<class A, class B>
class myClass
{
    template<class X, class ITER_T>
    struct map_type {
        typedef std::map<X, ITER_T> type;
    };

    template<class ITER_T>
    struct map_type<std::string, ITER_T> {
        typedef boost::unordered_map<A /* or std::string */, ITER_T> type;
    };

    typedef std::list<Object<A,B>> MyList;
    typedef map_type<A, typename MyList::iterator>::type MyMap;

    MyList mList;
    MyMap mMap;
};
模板
类myClass
{
模板
结构映射类型{
typedef std::映射类型;
};
模板
结构映射类型{
typedef boost::无序_映射类型;
};
typedef std::list MyList;
typedef map_type::type MyMap;
糜棱岩;
MyMap-mMap;
};

(对于C++11之前的版本,我会使用
boost::unordered_-map
而不是
std::unordered_-map

什么是“元字符串”?一个特定的类?一个实现特定接口的类?一个具有特定属性的类?在第一个代码块中,
MyMap
不应该这样定义吗
typedef std::map MyMap
?对不起,我不得不投反对票。你的答案被发布在你面前的
TartanLlama
答案合并了。我和他有电话我也有同样的答案,但我们几乎同时发布。谢谢你的回答因为你觉得你不得不否决我的答案,因为它的实质内容被纳入了另一个成员的帖子中,我也表示赞同。毕竟,你帖子的内容也基本上在他/她的帖子中。我在键入帖子的过程中分心了,所以在发布之前,我没有看到你的答案。宾果。但是,一般来说,我的目标是只对不正确/无效的答案进行否决,而不是对碰巧包含其他答案中内容的答案进行否决。但是,你以如此惩罚性的方式使用了否决票,因此我以实物形式作出了回应。谢谢你的回答谢谢你的回答。这非常有用。谢谢。我会我可能会使用这些方法的组合,也许会尽量避免使用条件句,谢谢你的回答:)对不起,我一直收到。。。阴影模板参数。内部模板与外部模板形成阴影。如何修复此问题?@FPGalero只需更改
map\u type
:)的模板参数名称是的,我没有尝试编译,已更新为使用不同的名称作为内部模板参数。在专门化中,我认为可以直接使用A或std::string(如注释中)。
template <class T> struct IsMetaString : std::false_type {};
template <> struct IsMetaString<std::string> : std::true_type {};
template< class A, class B>
struct MapType // default
{
    typedef std::list<Object<A,B>> MyList;
    typedef std::unordered_map<A,B> MyMap;

    MyList mList;
    MyMap mMap;
};


template<class B>
struct MapType<foo, B>
{
     typedef std::list<Object<foo, B>> MyList;
     typedef std::map<foo,B> MyMap;

     MyList mList;
     MyMap mMap;
};
template<class A, class B>
class myClass
{
    template<class X, class ITER_T>
    struct map_type {
        typedef std::map<X, ITER_T> type;
    };

    template<class ITER_T>
    struct map_type<std::string, ITER_T> {
        typedef boost::unordered_map<A /* or std::string */, ITER_T> type;
    };

    typedef std::list<Object<A,B>> MyList;
    typedef map_type<A, typename MyList::iterator>::type MyMap;

    MyList mList;
    MyMap mMap;
};