在尝试回答这个问题时,我发现自己需要为动态函数创建一系列参数,其中:
在运行时,可以使用标准容器和for循环来执行此操作。
无论如何,我想在编译时生成一组参数,以便能够将它们转发给可变参数。
因此,std::tuple似乎是显而易见的解决方案。
这里出现一个问题:在编译时给定一个大小N和一个默认的可构造类型T,我该如何编写一个函数来生成给定大小的元组?
我正在寻找这样的东西:
auto tup = gen<MyType, N>();
Run Code Online (Sandbox Code Playgroud)
在SO上,是一个基于递归生成器的结构的显着示例,但是我在基于函数的解决方案中苦苦挣扎,而我却找不到任何地方。
我有以下详细代码:
struct thing1 { int key, std::string value; };
struct thing2 { int key, std::string value; };
// ...
struct thingN { int key, std::string value; };
struct thing_map {
thing1 t1;
thing2 t2;
// ...
thingN tN;
std::string get(int key) {
if(t1.key == key) return t1.value;
if(t2.key == key) return t2.value;
// ...
if(tN.key == key) return tN.value;
throw std::runtime_error("bad key");
}
};
Run Code Online (Sandbox Code Playgroud)
我可以将things 重构为 an std::tuple<thing1, thing2, /* ... */ thingN>,这允许我使用 typed 访问它们std::get,因此不会丢失任何功能(即 …
我有一个可以简化为的用例:
#include <vector>
#include <ranges>
#include <tuple>
struct TDat
{
double x, y;
template <std::size_t I>
friend double &get(TDat &Dat)
{ if constexpr (I == 0) return Dat.x; else return Dat.y; }
template <std::size_t I>
friend double const &get(TDat const &Dat)
{ if constexpr (I == 0) return Dat.x; else return Dat.y; }
};
namespace std
{
template <>
struct tuple_size<TDat> : integral_constant<size_t, 2u> {};
template <size_t I>
struct tuple_element<I, TDat>
{ using type = double; };
} // std …Run Code Online (Sandbox Code Playgroud) 我目前正在学习 C++ 中的元编程,我正在尝试查看元组的元素是否是指针。我试过这种方法:
int a = 3, b = 4;
auto tup = std::make_tuple(&a, b);
std::cout << std::is_pointer<decltype(std::get<0>(tup))>::value; //prints 0
Run Code Online (Sandbox Code Playgroud)
我觉得这很奇怪,所以我检查了推断的类型 clang(我使用的是 clang-10),这是
__tuple_element_t<0UL, tuple<int *, int>
Run Code Online (Sandbox Code Playgroud)
它看起来像是某种内部类型。
为什么我会得到这种奇怪的类型以及获取元组元素的实际类型的正确方法是什么?我只有一个使用中间auto变量的解决方案,但几乎不是最佳的。
把一个std::unique_ptr内部std::tuple工作没有任何问题,但是当tuple包含另一个tuple具有共同unique_ptr的元素,则编译器会引发错误。
例子:
std::tuple<int, std::unique_ptr<Entity>> tupleA {1, std::move(new Entity)};
//this line throws an error!
std::tuple<std::tuple<int, int>, std::unique_ptr<Entity>> tupleB {{1, 1}, std::move(new Entity)};
Run Code Online (Sandbox Code Playgroud)
error: no matching constructor for initialization of ´std::tuple<std::tuple<int, int>,std::unique_ptr<Entity>>´
note: candidate constructor template not viable: cannot convert initializer list argument to ´std::allocator_arg_t´
Run Code Online (Sandbox Code Playgroud)
这里的问题究竟是什么?
我正在编写一个简单的实体组件系统框架,我想在其中使用可变参数模板来获得更灵活的接口。对于每个组件,我都有偏移量(从块内存的开始)存储在std::array. 在我的 'update()' 方法中,我想从这个数组中读取偏移量,将它添加到块的指针并将指针(指向特定组件)作为参数直接传递给 lambda。我尝试使用std::index_sequence,但无法同时使用此索引作为元组和数组的索引。预先感谢您的帮助。
template<typename ...Cn>
class SystemGroup {
public:
using OffsetArray = std::array<uint16_t, sizeof...(Cn)>;
static constexpr size_t kMaxGroups = 16;
static constexpr GroupIndex kInvalidIndex = -1;
struct Group {
static constexpr uint8_t kNumComponents = sizeof...(Cn);
OffsetArray componentOffsets;
Chunk *pFirstChunk;
};
};
template<typename ...Cn>
void SystemGroup<Cn...>::update() {
for (auto group : m_groups) {
// iterate over archetype's chunks
ecs::Chunk *pChunk = group.pFirstChunk;
do {
// get component data
std::tuple<Cn*...> pointers;
// Here is the problem. …Run Code Online (Sandbox Code Playgroud) c++ template-meta-programming variadic-templates stdtuple c++20
我经常遇到情况,特别是在C++中进行排序,我在比较一系列字段以比较更大的结构.一个简化的例子:
struct Car{
Manufacturer make;
ModelName model;
Year year;
};
bool carLessThanComparator( const Car & car1, const Car & car2 ){
if( car1.make < car2.make ){
return true;
}else if( car1.make == car2.make ){
if( car1.model < car2.model ){
return true;
}else if( car1.model == car2.model ){
if( car1.year < car2.year ){
return true;
}
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
我的本能方法似乎很麻烦,特别是对于超过3个领域.你将如何在C++中构建这一系列的比较?其他语言是否提供更简洁或优雅的语法?
所以我给了一个std::tuple<T...>,我想创建一个接受的函数指针T...,目前这就是我所拥有的;
template<typename... Arguments>
using FunctionPointer = void (*)(Arguments...);
using FunctionPtr = FunctionPointer<typename std::tuple_element<0, V>::type,
typename std::tuple_element<1, V>::type,
typename std::tuple_element<2, V>::type>;
Run Code Online (Sandbox Code Playgroud)
但是我似乎无法找到一种方法来做到这一点,而无需手动输入每个索引0, ..., tuple_size<V>::value.FunctionPtr是在上下文中定义的,其中V=std::tuple<T...>(也有一个可变参数模板(因此我不能直接传递T...))
我想我需要生成一些索引列表,并做一些黑魔法..
我有一个具有类似元组的界面的自定义类.因为我想我的代码尽可能通用的,我认为这将是我的基础上的功能的算法是一个好主意std::get,std::tuple_size,std::tuple_element所以你只需要专注这些功能用我的算法.让我们称之为需要这些功能特化的概念Tuple.
现在我试图总结一个组件Tuple.函数声明应该是这样的:
template <class Tuple>
int sum_components(const Tuple& t);
Run Code Online (Sandbox Code Playgroud)
我想有很多模板编程涉及但我无法弄清楚如何做到这一点.
对于添加,我只会使用全局的重载+ operator.
我正在使用c ++ 1z.
在c ++ 14中,我有以下类型:
std::tuple<int[2], int>;
Run Code Online (Sandbox Code Playgroud)
我该如何正确初始化它?这个
std::tuple<int[2], int> a {{2,2},3};
Run Code Online (Sandbox Code Playgroud)
给我这个错误:
/ usr/include/c ++/5/tuple:108:25:error:用作初始化程序的数组
这个:
std::tuple<std::array<int,2>, int> a {{2,2},3};
Run Code Online (Sandbox Code Playgroud)
有效,但我希望能够使用标准的C风格数组
c++ ×10
stdtuple ×10
templates ×3
c++17 ×2
c++20 ×2
boost-tuples ×1
c++-concepts ×1
c++11 ×1
c++14 ×1
coding-style ×1
pointers ×1
range-v3 ×1
stdarray ×1
stl ×1
tuples ×1
types ×1
unique-ptr ×1