gpt4 book ai didi

c++ - 两种类型的可变参数扩展

转载 作者:行者123 更新时间:2023-12-03 20:23:41 26 4
gpt4 key购买 nike

如何进行两种类型的可变参数扩展?这是我想要实现的目标:

#include <vector>
#include <iostream>

class test
{
public:
std::vector< std::pair< float, int > > vec;
template<typename... T1, typename... T2>
test( T1... one, T2... two )
{
(
[&](float first, int second)
{
vec.emplace_back( std::pair< float, int >( first, second ) );
std::cout << first << ", " << second << std::endl;
}( one, two ),
...
);
}
};

int main()
{
test t
{
1.f,
1,
2.f,
2,
3.f,
3
};

return 0;
}

test 必须像在 main 中一样进行初始化。我希望 test 的构造函数中的用法保持相似。

这是 va_list 的工作概念。不幸的是,我需要为参数传递一个计数,或者我需要传递一个魔数(Magic Number)终止符(我选择了魔数(Magic Number)终止符)。

#include <cstdarg>
#include <iostream>
#include <vector>

constexpr int END_OBJECT = 890123; // magic number

class test {
public:
std::vector<std::pair<int, double>> vec;

enum { is_name, is_data, is_max };

test(char ch, ...) {
std::pair<int, double> buf;

va_list b;
va_start(b, ch);
for (int i = 0;; i++) {
auto is = i % is_max;

if (is == is_name) {
if ( (buf.first = va_arg(b, int)) == END_OBJECT )
break;
} else if (is == is_data) {
buf.second = va_arg(b, double);
vec.emplace_back(buf);
}
}
va_end(b);
std::cout << ch << std::endl;
for (auto &x : vec)
std::cout << '\t' << x.first << ", " << x.second << std::endl;
}
};

int main() {
test t
{
'x',
1,
2.0,
3,
4.0,
5,
6.0,
END_OBJECT
};

return 0;
}

我想要一个使用包扩展的更现代的版本。

最佳答案

有趣的是,这基本上是带有模板参数的 FizzBu​​zz,而且它实际上是一个不错的挑战。

我能想到的 C++14 中最简单的方法是使用 std::index_sequence。 https://godbolt.org/z/dm3F9u

#include <vector>
#include <utility>
#include <tuple>

template <typename... TArgs, size_t... Is>
std::vector<std::pair<float, int>> pair_off(std::tuple<TArgs...> args, std::index_sequence<Is...>) {
return std::vector<std::pair<float, int>> { std::make_pair(std::get<(Is << 1)>(args), std::get<((Is << 1) + 1)>(args))... };
}


template <typename... TArgs>
std::vector<std::pair<float, int>> pair_off(TArgs&&... args) {
return pair_off(std::forward_as_tuple(std::forward<TArgs>(args)...), std::make_index_sequence<(sizeof...(TArgs) >> 1)>{});
}

std::vector<std::pair<float, int>> test() {
return pair_off(1.1f, 1, 2.2f, 2, 3.3f, 3);
}

基本上,首先您将参数打包到一个元组中。然后,您将索引序列设为参数列表大小的一半。然后扩展该索引序列,将其传递给 std::get。

模板的作用是:

for (int i=0; i<list.size()/2; i++) { 
output.push_back( std::make_pair(list[i*2], list[i*2+1]) );
}

关于c++ - 两种类型的可变参数扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58617614/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com