我想要一个我正在编写的函数来返回一个N foo
s的元组,其值为N(N不是代码的一部分)。
如果它是C ++ 14,我可以绕过实际声明任何东西,只使用auto
作为返回类型,但这在C ++ 11中不起作用。我不想使用-> auto decltype
,因为这意味着很多的文字,我不妨写一下,例如std::tuple{foo, foo, foo, foo}
。
另一种选择是将返回类型设为std::array<foo, N>
;这应该可行。但是,我想知道的是,如果我没有完全提到<array>
,我实际上并不需要它的功能。
答案 0 :(得分:4)
typedef struct {
char **historyCommand;
int usedSize;
int maximumSize;
} HistoryArray;
void CreateHistoryArray(HistoryArray *HistoryArray) {
HistoryArray->historyCommand = malloc(INITIAL_SIZE * sizeof(char *));
HistoryArray->usedSize = 0;
HistoryArray->maximumSize = INITIAL_SIZE;
}
void ExpandHistoryArray(HistoryArray *HistoryArray, int newSize) {
HistoryArray->historyCommand = realloc(HistoryArray->historyCommand, newSize * sizeof(char *));
HistoryArray->maximumSize = newSize;
}
void AddHistoryValue(HistoryArray *HistoryArray, char historyCommand[]) {
historyCommand[HistoryArray->usedSize] = malloc(strlen(historyCommand) + 1);
strcpy(HistoryArray->historyCommand[HistoryArray->usedSize], historyCommand);
HistoryArray->usedSize++;
if (HistoryArray->usedSize == HistoryArray->maximumSize) {
ExpandHistoryArray(HistoryArray, HistoryArray->maximumSize * 2);
}
}
void freeHistoryArray(HistoryArray *a) {
for (int i = 0; i < a->usedSize; i++) {
free a->historyCommand[i];
}
a->usedSize = 0;
a->maximumSize = 2;
a->historyCommand = realloc(a->historyCommand, a->maximumSize * sizeof(char *));
}
HistoryArray historyArray;
答案 1 :(得分:3)
使用integer_sequence [integer_seq.h]的外部实现,c ++ 11方法对c ++ 14进行样式设计可能如下所示:
#include <tuple>
#include <utility>
#include <iostream>
#include <initializer_list>
#include "integer_seq.h"
using namespace redi;
template <class T, std::size_t N, class = make_index_sequence<N>>
struct tuple_generator;
template <std::size_t, class T>
using typer = T;
template <class T, std::size_t N, std::size_t... Is>
struct tuple_generator<T, N, index_sequence<Is...>> {
using type = std::tuple<typer<Is, T>...>;
};
int main() {
static_assert(std::is_same<tuple_generator<int, 3>::type, std::tuple<int, int, int>>::value, "!");
}
答案 2 :(得分:2)
我要从@Smeeheey的回答中回答这个问题,回答我提出的另一个问题:C++ parameter pack, constrained to have instances of a single type?
关联是,你的问题与tuple
没什么关系,真的,
如何重复多次重复包含相同类型的参数包?
最直截了当的答案是,使用std::make_index_sequence
和包扩展:
#include <tuple>
#include <utility>
template <typename T, unsigned n>
struct repeat_tuple {
template <unsigned>
struct blah {
using type = T;
};
template <typename IS>
struct helper;
template <unsigned ... Is>
struct helper<std::integer_sequence<unsigned, Is...>> {
using type = std::tuple<typename blah<Is>::type...>;
};
using type = typename helper<std::make_integer_sequence<unsigned, n>>::type;
};
template <typename T, unsigned n>
using repeat_tuple_t = typename repeat_tuple<T, n>::type;
static_assert(std::is_same<repeat_tuple_t<int, 3>, std::tuple<int, int, int>>::value, "");
int main() {}
这最终与W.F。的答案相同,但也许有点苛刻。编辑:我猜他在答案中回溯了C ++ 14的特征。
与tuple_cat
方法不同,此方法也适用于除元组之外的其他方法。
事实上,我猜std::tuple
可能是模板模板参数......
:邪恶的眼睛:
答案 3 :(得分:-1)
常规功能无法实现这一点。
函数的返回类型是固定的,不能更改。具有不同类型的元组每个都是不同的类型,因此您不能拥有一个返回不同元组类型的函数。
示例:与tuple<int, int>
tuple<int,int,int>
是一种不同的类型
话虽如此,您可以使用函数模板执行此操作(make_shared
以这种方式实现),调用程序在进行函数调用时显式指定返回的元组类型。我不认为这是好的可用性,因为元组是冗长的。
使用std :: array(或std :: vector)可能是更容易的路径。