如何有效地计算变体向量上的函数?
How to efficiently calculate a function on a vector of variants?
我有一个变体向量,可以存储 uint64_t 和双精度类型,我想计算它们的中位数。
在任何给定时间,向量完全由 uint64_t 或双数
组成
目前我的解决方案如下所述,但在代码方面似乎是多余的,我想知道是否有更好的方法来实现这个结果。
typedef std::variant<uint64_t, double> data_variant;
data_variant calculate_median(const std::vector<data_variant>& data) {
auto index = data.back().index();
// uint64_t
if (index == 0) {
std::vector<uint64_t> vec;
for (auto& i: data) {
vec.emplace_back(std::get<uint64_t>(i));
}
const auto median_it = vec.begin() + vec.size() / 2;
std::nth_element(vec.begin(), median_it , vec.end());
return *median_it;
// double
} else if (index == 1) {
std::vector<double> vec;
for (auto& i: data) {
vec.emplace_back(std::get<double>(i));
}
const auto median_it = vec.begin() + vec.size() / 2;
std::nth_element(vec.begin(), median_it , vec.end());
return *median_it;
}
}
在简化代码方面,您可以通过复制和简单地
接收data
data_variant calculate_median (std::vector<data_variant> data)
{
auto const median_it = data.begin() + (data.size() >> 1u);
std::nth_element(data.begin(), median_it, data.end());
return *median_it;
}
但是,也许,这种松散的效率。
重复代码的区别是一个类型,所以你可以像这样分解出一个函数模板:
template<typename T>
data_variant calculate_median_impl(const std::vector<data_variant>& data)
{
std::vector<T> vec;
for (auto& i: data)
{
vec.emplace_back(std::get<T>(i));
}
const auto median_it = vec.begin() + vec.size() / 2;
std::nth_element(vec.begin(), median_it , vec.end());
return *median_it;
}
然后select分别调用哪一个:
data_variant calculate_median(const std::vector<data_variant>& data)
{
return data.back().index()
? calculate_median_impl<uint64_t>(data)
: calculate_median_impl<double>(data);
}
我有一个变体向量,可以存储 uint64_t 和双精度类型,我想计算它们的中位数。
在任何给定时间,向量完全由 uint64_t 或双数
组成目前我的解决方案如下所述,但在代码方面似乎是多余的,我想知道是否有更好的方法来实现这个结果。
typedef std::variant<uint64_t, double> data_variant;
data_variant calculate_median(const std::vector<data_variant>& data) {
auto index = data.back().index();
// uint64_t
if (index == 0) {
std::vector<uint64_t> vec;
for (auto& i: data) {
vec.emplace_back(std::get<uint64_t>(i));
}
const auto median_it = vec.begin() + vec.size() / 2;
std::nth_element(vec.begin(), median_it , vec.end());
return *median_it;
// double
} else if (index == 1) {
std::vector<double> vec;
for (auto& i: data) {
vec.emplace_back(std::get<double>(i));
}
const auto median_it = vec.begin() + vec.size() / 2;
std::nth_element(vec.begin(), median_it , vec.end());
return *median_it;
}
}
在简化代码方面,您可以通过复制和简单地
接收data
data_variant calculate_median (std::vector<data_variant> data)
{
auto const median_it = data.begin() + (data.size() >> 1u);
std::nth_element(data.begin(), median_it, data.end());
return *median_it;
}
但是,也许,这种松散的效率。
重复代码的区别是一个类型,所以你可以像这样分解出一个函数模板:
template<typename T>
data_variant calculate_median_impl(const std::vector<data_variant>& data)
{
std::vector<T> vec;
for (auto& i: data)
{
vec.emplace_back(std::get<T>(i));
}
const auto median_it = vec.begin() + vec.size() / 2;
std::nth_element(vec.begin(), median_it , vec.end());
return *median_it;
}
然后select分别调用哪一个:
data_variant calculate_median(const std::vector<data_variant>& data)
{
return data.back().index()
? calculate_median_impl<uint64_t>(data)
: calculate_median_impl<double>(data);
}