我试图使用静态多态和模板来创建一个可以容纳更多类型的容器,从我对模板的了解来看,这是不可能的,但我希望我错了,有一种方法。我有以下类:
template<class Derived>
class base
{
public:
base(string);
void clean()
{
cout << "I'm cleannig \n";
}
void process()
{
static_cast<Derived*>(this)->setup();
static_cast<Derived*>(this)->run();
static_cast<Derived*>(this)->cleanup();
}
string name;
};
template<class Derived>
base<Derived>::base(string y):name(y)
{
}
class derived : public base<derived>
{
friend class base<derived>;
void setup() {cout << "derived setup \n"; }
void run() { cout << "derived run \n"; }
void cleanup() { cout << "derived cleanup \n"; }
};
class derived1 : public base<derived1>
{
friend class base<derived1>;
void setup() {cout << "derived1 setup \n"; }
void run() { cout << "derived1 run \n"; }
void cleanup() { cout << "derived1 cleanup \n"; }
};
我想创建一个可以容纳它们的容器,我尝试了这个代码-
template <class T>
class Y{
public:
std::vector<base<T>> m_vec;
};
template <typename T>
class D:public Y<T>
{
public:
friend class Y<T>;
void print()
{
for(auto& e: Y<T>::m_vec)
{
e.process();
}
}
};
int main()
{
base<derived>* b = new base<derived>;
base<derived1>* c = new base<derived1>;
D<derived> y;
y.m_vec.push_back(b);
y.m_vec.push_back(c);
y.print();
}
但它不工作,我试图这样做:
y.m_vec.push_back(static_cast<base<derived>>(c));
我得到这个错误:
错误:没有匹配函数用于调用'std::vector,std::allocator〉〉::push_back(base*&)' y.m_vec.push_back(b);
2条答案
按热度按时间bnl4lu3b1#
经过一些测试和挖掘,答案是没有办法做到这一点。但是你可以使用std::any,如@formerlyknownas_463035818建议的,将std::vector声明为:
代替
然后使用boost demangle函数来获取类型-
然后使用某种工厂函数将any_cast转换为您需要的类型
或者不使用demangle name和use string compare,你可以使用any类的type()函数,并像这样比较typeid:
m528fe3b2#
只要在调用
process()
函数时没有关于实际类型的信息,这是不可能的。从C++17开始,你可以使用
std::variant
来存储类型信息。你可以让process
成为一个静态函数,它的参数是从base
派生的类的示例。然后你可以创建一个
std::vector
的std::variant
的A
和B
。通过visit语句中的泛型lambda调用process()
。x一个一个一个一个x一个一个二个x
使用C++23可以简化得更多。
有四点不同:
1.包含已被C++23 module
import std
取代。std::cout
已被std::print
取代。process
现在是一个普通的非静态成员函数,在新的C++23表示法中具有显式的this
。它仍然是一个模板,但受到C++20 concept的约束。1.调用现在使用普通的成员函数调用语法
a_or_b.process();
。