C++ 如何将支持的类型添加到现有的旧std::list操作函数(即模板?)
我有一个关于将支持的类型添加到现有的遗留std::list操作函数的特定问题。我试着用模板来做这件事,但没有成功,所以我很感激任何关于如何更好地使用模板或完全使用不同机制的建议。请看看我下面的情景,如果有任何想法,请告诉我。提前感谢您的帮助 我目前有两个类型为A的std::列表,并为它们提供了插入/删除/获取/etc函数。下面显示了一个简化的代码段C++ 如何将支持的类型添加到现有的旧std::list操作函数(即模板?),c++,templates,stdlist,C++,Templates,Stdlist,我有一个关于将支持的类型添加到现有的遗留std::list操作函数的特定问题。我试着用模板来做这件事,但没有成功,所以我很感激任何关于如何更好地使用模板或完全使用不同机制的建议。请看看我下面的情景,如果有任何想法,请告诉我。提前感谢您的帮助 我目前有两个类型为A的std::列表,并为它们提供了插入/删除/获取/etc函数。下面显示了一个简化的代码段 typedef std::list<A*> TListA; TListA ListA1; TListA ListA2; void In
typedef std::list<A*> TListA;
TListA ListA1;
TListA ListA2;
void InsertIntoListA(A* pA)
{
TListA& ListA = IsBoo()? ListA1 : ListA2;
ListA.push_back(pA);
}
typedef std::list TListA;
TListA列表1;
TListA ListA2;
无效插入列表A(A*pA)
{
TListA&ListA=IsBoo()?ListA1:ListA2;
ListA.推回(pA);
}
现在,我发现我需要添加类型B,并且我考虑使用模板来添加这个新类型(如下所示),但结果发现有两个问题
template <typename T>
void InsertIntoListT(T* pT)
{
std::list<T*>& List;
if (IsA())
List = IsBoo()? ListA1 : ListA2;
else
List = IsBoo()? ListB1 : ListB2;
List.push_back(pT);
}
模板
无效插入列表T(T*pT)
{
std::列表&列表;
if(IsA())
List=IsBoo()?ListA1:ListA2;
其他的
List=IsBoo()?ListB1:ListB2;
列表。推回(pT);
}
问题1:
我不能有“std::list&list”,因为它是通过引用的,所以需要分配给实际的列表。所以我最终会得到这样的结果,这并不理想
template <typename T>
void InsertIntoListT(T* pT)
{
if (IsA()) {
TListA& ListA = IsBoo()? ListA1 : ListA2;
ListA.push_back(pT);
} else {
TListB& ListB = IsBoo()? ListB1 : ListB2;
ListB.push_back(pT);
}
}
模板
无效插入列表T(T*pT)
{
if(IsA()){
TListA&ListA=IsBoo()?ListA1:ListA2;
ListA.推回(pT);
}否则{
TListB&ListB=IsBoo()?ListB1:ListB2;
列表b.推回(pT);
}
}
问题2:
我在A到B或B到A的转换中遇到错误。我认为这是因为给定模板T,编译器将枚举“ListA.push_back”和“ListB.push_back”的所有四种可能性,这导致将A插入到列表A,将B插入到列表A,将A插入到列表B,并将B插入到列表B,其中只有两个是有效的。所以我最终得到了这样的结果,我认为这违背了使用模板的目的
template <typename T>
void InsertIntoListT(T* pT)
{
if (IsA()) {
TListA& ListA = IsBoo()? ListA1 : ListA2;
ListA.push_back(reinterpret_cast<A*>(pT));
} else {
TListB& ListB = IsBoo()? ListB1 : ListB2;
ListB.push_back(reinterpret_cast<B*>(pT));
}
}
模板
无效插入列表T(T*pT)
{
if(IsA()){
TListA&ListA=IsBoo()?ListA1:ListA2;
列表a.推回(重新解释铸件(pT));
}否则{
TListB&ListB=IsBoo()?ListB1:ListB2;
列表b.推回(重新解释铸件(pT));
}
}
不要将所有功能混用在一个函数中。这是非常糟糕的做法。使用类似
void InsertIntoListImpl(A* p)
{
(IsBoo() ? ListA1 : ListA2).push_back(p);
}
void InsertIntoListImpl(B* p)
{
(IsBoo() ? ListB1 : ListB2).push_back(p);
}
template<typename T>
void InsertIntoList(T* p)
{
InsertIntoListImpl(p);
}
void InsertIntoListImpl(A*p)
{
(IsBoo()?列表A1:列表A2)。向后推(p);
}
无效插入列表impl(B*p)
{
(IsBoo()?ListB1:ListB2)。向后推(p);
}
模板
无效插入列表(T*p)
{
插入列表植入(p);
}
或者一些特征,或者别的什么。但无论如何,在一个函数中没有很多条件
为什么不将实际列表传递给函数进行插入?这会更好。显然,您不能在函数模板内进行列表类型切换,因为每个模板实例化只知道这两种类型中的一种。所以你必须在函数外切换。有一种可能性:
TListA& getList(bool isBoo, A* /*dummy*/)
{
return isBoo ? ListA1 : ListA2;
}
TListB& getList(bool isBoo, B* /*dummy*/)
{
return isBoo ? ListB1 : ListB2;
}
template <typename T>
void InsertIntoListT(T* pT)
{
auto& theList = getList(IsBoo(), (T*)NULL);
theList.push_back(pT);
}
TListA&getList(bool-isBoo,A*/*dummy*/)
{
返回isBoo?列表A1:列表A2;
}
TListB和getList(bool-isBoo,B*/*dummy*/)
{
返回isBoo?列表B1:列表B2;
}
模板
无效插入列表T(T*pT)
{
auto&theList=getList(IsBoo(),(T*)NULL);
列表。推回(pT);
}
虚拟仅用于siwtching类型-可以通过函数模板和专门化来完成,但这很难看。根据列表变量的实际性质,
getList
功能可以通过其他方式编写。可能更通用,也可能不通用。创建两个函数。。。InsertIntoList和InsertIntoList,InsertIntoList…您可能在这里遇到了设计问题。为什么在输入InsertIntoListT()
之前,您不知道自己在使用什么列表?感谢各位的反馈。Gorpik,在输入InsertIntoListT之前我确实知道类型。我只是在寻找一种重用代码的方法。谢谢Arne。这是一种感知类型并实现高度代码重用的有趣方式。我一定会尝试一下,让你知道我的结局!永远感谢你的回答。我认为这绝对是一个使用模板的更优雅的解决方案。我认为,在您的结构中,我们的想法是将特定于类型的代码放入特定的实例化(即InsertIntoListImpl),并将与类型无关的代码放入模板函数(即InsertIntoList)?在我的简化示例中,我实际上没有任何类型不可知的代码,但我在真实的类中有。