c++ - Generic polymorphism: create a variable of whatever type and use it
问题描述
I believe this is also called "type erasure". Consider the following not too minimal and not working code example:
#include <string>
#include <tuple>
std::pair<int, int> foo(int);
std::pair<std::string, std::string> foo(std::string);
struct S
{
S(int);
S(std::string);
};
int main()
{
const auto some_bool{ false };
const auto data =
[ some_bool ]
()
{
if(some_bool)
{
return foo(42);
}
else
{
return foo("fourty-two"); // error: different return type
}
}
();
const auto s{ data.first };
// use s and data.second regardless of it's type
}
I would like to:
- keep
data
constant - not duplicate all the following code inside an
if...else
- avoid templates if possible because of the horrible error messages and the need to implement in a header
- avoid putting the rest of the code in a separate function because it is on the same level of abstraction as creating
s
.
What would be a nice approach?
解决方案
为了能够使用.first
and .second
on data
,您将需要一对两个类型擦除的值,因为您需要避免擦除它是一对的事实。IEstd::pair<erased_type, erased_type>
在您的示例中,您提前知道类型列表,因此您应该使用std::variant<>
创建一个可以包含已知替代方案之一的类型。如果您在编译时不知道该列表,则可以使用std::any
。
using int_or_string = std::variant<int, std::string>;
using data_type = std::pair<int_or_string, int_or_string>;
接下来,您可以强制 lambda 返回此擦除的类型,并让各种返回值隐式转换为它:
[...]
using int_or_string = std::variant<int, std::string>;
const auto data =
[ some_bool ]
() -> std::pair<int_or_string, int_or_string>
{
[...]
推荐阅读
- spring-boot - 如何将 RefreshScope 与启用的引导程序一起使用
- javascript - 在 React 中使用 [...Array(stateValue)] 时遇到问题。不确定这是否是正确的方法
- ruby-on-rails - Rails 使用 zip 按年份匹配的两个变量
- go - Golang 导入问题
- python - 使用 scipy 和 matplotlib 绘制信号频谱图(表面肌电图)
- django - BSModalDeleteView (django-bootstrap-modal-form) 忽略 get_success_url
- c# - 有没有办法在 Kafka 中回滚已提交的偏移量?
- c++ - C++ 打开一个没有库的窗口
- java - 如何在 SharedPreferences 中存储来自 url 的 JSONObject
- fuzzy-logic - 模糊规则视图