如何使用模板根据类型将元素添加到各种容器 [英] How to add element to various container depending of type using template

查看:41
本文介绍了如何使用模板根据类型将元素添加到各种容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很愚蠢的问题,但希望您能帮助我.

I've got rather silly question but I hope that you can help me with that.

我有多个向量类,并且这些向量具有不同的存储类型.

I've got class with multiple vectors, and this vectors have different storage types.

class BaseClass{
  std::string Name;
}

class B : public BaseClass{

}
class C : public BaseClass{

}

class A{
  vector<std::pair<std::string, B>> V1;
  vector<std::pair<std::string, C>> V2;
}

在我的A类中,有一个模板函数可以向这些向量添加元素:

inside my class A there is a template function to add elements to this vectors:

template <class T>  void addElement(T Obj);

我希望这种情况发生:

A a;
B b;
C c;


a.addElement<B>(b) -> then element b is added to vector V1
a.addElement<C>(c) -> then element c is added to vector V2

我想到了这样的东西:

template <class T>  void addElement(T Obj){
  std::pair<std::string, T> AddedPair(Obj.Name, Obj);

   if (typeid(T) == typeid(B)) 
    V1.push_back(AddedPair);

   if (typeid(T) == typeid(C)) 
    V2.push_back(AddedPair);

}

但是不幸的是,该代码无法编译,因为以某种方式将模板作为一个整体进行编译,如果我将B用作模板参数,则尽管该程序永远无法达到可进行这种转换的地步,但编译器无法将B转换为C :(

But unfortunetly this code won't compile because somehow template is compiled as a whole and if I use B as a template argument then compiler cannot convert B to C despite that program will never reach a point where this convertions can happened :(

您有什么建议我该如何解决?我会非常感激的.

Do you have any suggestions how can I solve this problem? I would be very greatful.

推荐答案

而不是拥有

template <class T>  void addElement(T Obj);

只需重载该函数即可.那会给你

Just overload the function instead. That would give you

void addElement(const B& Obj)
{
    V1.push_back({Obj.Name, Obj});
}

void addElement(const C& Obj)
{
    V2.push_back({Obj.Name, Obj});
}

这为您节省了专门化模板或需要C ++ 17的所有语法,并且

This saves you all the syntax of specializing the template or needing C++17 and if constexpr to make the decision at compile time.

原因

template <class T>  void addElement(T Obj){
std::pair<std::string, T> AddedPair(Obj.Name, Obj);

    if (typeid(T) == typeid(B)) 
        V1.push_back(AddedPair);

    if (typeid(T) == typeid(C)) 
        V2.push_back(AddedPair);

}

如果if块需要有效(即使永远无法到达),则每个代码都不起作用,但这不是因为您要在向量中添加其他类型.如果constexpr 有帮助,但我发现重载与输入一样多,并且使代码向后不兼容.

Doesn't work is the code in each if block needs to be valid (even if it could never be reached), but it can't be because you would be adding a different type into the vectors. if constexpr helps but I find overloading is just as much typing and makes the code non-backwards compatible.

这意味着您将不得不像这样专门化模板

That means you would either have to specialize the template like

template <class T>  void addElement(T Obj);

template <>  void addElement(B Obj)
{
    V1.push_back({Obj.Name, Obj});
}   
template <>  void addElement(C Obj)
{
    V1.push_back({Obj.Name, Obj});
}

或使用 if constexpr :

template <class T>  void addElement(T Obj){
std::pair<std::string, T> AddedPair(Obj.Name, Obj);

    if constexpr(std::is_same_v<T, B>) 
        V1.push_back(AddedPair);

    if constexpr(std::is_same_v<T, C>) 
        V2.push_back(AddedPair);

}       

这篇关于如何使用模板根据类型将元素添加到各种容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆