Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 访问多态类型,如变体,但不知道确切的子类型_C++_Polymorphism_Type Erasure_Dynamic Dispatch - Fatal编程技术网

C++ 访问多态类型,如变体,但不知道确切的子类型

C++ 访问多态类型,如变体,但不知道确切的子类型,c++,polymorphism,type-erasure,dynamic-dispatch,C++,Polymorphism,Type Erasure,Dynamic Dispatch,有时,了解多态对象的实际子类型是有益的,比如确保在重复调用虚拟函数的循环中不会发生虚拟调用。使std::variant可扩展到库的最终用户是一件非常痛苦的事情,使用一个接口更好 理想情况下,我可以这样做: struct base{ 虚拟void foo()=0; }; 派生结构:基{ 虚拟void foo()重写{} }; //样品 base*b=新的派生{}; b->使用子类型([](自动*子类型)调用子类型{ 静态断言(std::is_same_v); }); 当然,生活并不是那么理想,我

有时,了解多态对象的实际子类型是有益的,比如确保在重复调用虚拟函数的循环中不会发生虚拟调用。使
std::variant
可扩展到库的最终用户是一件非常痛苦的事情,使用一个接口更好

理想情况下,我可以这样做:

struct base{
虚拟void foo()=0;
};
派生结构:基{
虚拟void foo()重写{}
};
//样品
base*b=新的派生{};
b->使用子类型([](自动*子类型)调用子类型{
静态断言(std::is_same_v);
});
当然,生活并不是那么理想,我需要以某种方式注入这个函数。我在考虑某种CRTP技巧,但我一次又一次地遇到同样的问题,就是无法擦除传递的通用lambda函数


TL;DR:是否可以在没有大量样板文件和事先知道所有子类型的情况下对多态类型执行动态调度?

您可以使用
derived*test=dynamic\u cast(object)
测试特定子类型:如果
object
确实是
derived
那么
test
将是指向它的指针,但是,如果它实际上是一个
base
,那么
test
将是
nullptr

解决上述问题需要对模板代码进行运行时/动态链接时间具体化。这是C++缺乏的一个特点。 适度的限制消除了这种需要,但都有权衡。大多数都需要某个地方支持的类型列表,或支持的操作列表

奇特的替代对象模型允许将vtable从实例中分离出来,并在缓冲区和类似区域中“RLE”类型,但这也不符合您所描述的

TL;“不”是你问题的答案,你不能这么做


因此,它最适合于具体的实际问题。根据我的经验,如果你有一个实际的用例,9/10在你的实际用例中有一个隐含的限制,使你的问题可以解决

相反,你会产生一个抽象的孤子,它足以解决你真正的问题。问题是你的抽象解决方案不可能解决

当然,99/100这样的问题并没有他们正在解决的实际问题


如果你有一个实际的具体问题,我鼓励你发表一个关于它的问题,而不是这个抽象的问题。我的爱好是找到一些合理答案为“否”的帖子,并提供不合理的“是”答案。

我想你误解了,我想推断出子类型并用它调用回调,就像
std::visit
那样。挑战在于我不知道选项(亚型的种类)@Peter Lenkefi好的,那么你的TL;DR section可能会否定我的答案:您需要一整套测试和回调。如果您不能使用通用lambda,您会高兴吗?例如,
b->invoke_与_子类型([](派生和子类型){/*…*/})?@Justin我相信那会破坏目的。lambda是泛型的这一事实引入了大部分复杂性:“我一次又一次地遇到同一个问题,我只是无法擦除传递的泛型lambda函数。”@FrançoisAndrieux,但你肯定必须知道lambda体中的
派生
,否则你不能使用它。我看不出将lambda变成通用lambda的好处。@Justin我认为目标是获得具体类型,但只使用公共
base
接口。这是否真的有用还有争议,但这并不重要。问题不在于申请。例如,我可以想象的另一个用例是在functor中获得
sizeof(subtype)
。这个问题让人大吃一惊。这看起来是可以解决的,但每一条路似乎都通向一堵坚硬的砖墙。