Создайте перегруженный набор конструкторов:
#include <tuple>
#include <cstddef>
template <typename T, std::size_t M>
using indexed = T;
template <typename T, std::size_t M, std::size_t... Is>
struct initializer : initializer<T, M, sizeof...(Is) + 1, Is...>
{
using initializer<T, M, sizeof...(Is) + 1, Is...>::initializer;
initializer(indexed<T, Is>... ts)
{
// ts is a pack of std::tuple<int, char, double>
}
};
template <typename T, std::size_t M, std::size_t... Is>
struct initializer<T, M, M, Is...> {};
using foo = initializer<std::tuple<int, char, double>, 20>;
// tuples limit+1 ~~~^
int main()
{
foo({1,'2',3.0});
foo({1,'2',3.0}, {4,'5',6.0});
foo({1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0});
}
ДЕМО
Сгенерируйте перегруженный набор операторов вызова функций:
#include <tuple>
#include <cstddef>
template <typename T, std::size_t M>
using indexed = T;
template <typename T, std::size_t M, std::size_t... Is>
struct initializer : initializer<T, M, sizeof...(Is) + 1, Is...>
{
using initializer<T, M, sizeof...(Is) + 1, Is...>::operator();
int operator()(indexed<T, Is>... ts) const
{
// ts is a pack of std::tuple<int, char, double>
return 1;
}
};
template <typename T, std::size_t M, std::size_t... Is>
struct initializer<T, M, M, Is...>
{
int operator()() const { return 0; }
};
static constexpr initializer<std::tuple<int, char, double>, 20> foo = {};
// tuples limit+1 ~~~^
int main()
{
foo({1,'2',3.0});
foo({1,'2',3.0}, {4,'5',6.0});
foo({1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0});
}
ДЕМО 2
Создайте (или сгенерируйте с помощью макросов препроцессора) набор перегрузок, которые передают аргументы в одну реализацию:
#include <array>
#include <tuple>
using K = std::tuple<int, char, double>;
void foo(const std::array<K*, 5>& a)
{
// a is an array of at most 5 non-null std::tuple<int, char, double>*
}
void foo(K p0) { foo({&p0}); }
void foo(K p0, K p1) { foo({&p0, &p1}); }
void foo(K p0, K p1, K p2) { foo({&p0, &p1, &p2}); }
void foo(K p0, K p1, K p2, K p3) { foo({&p0, &p1, &p2, &p3}); }
void foo(K p0, K p1, K p2, K p3, K p4) { foo({&p0, &p1, &p2, &p3, &p4}); }
int main()
{
foo({1,'2',3.0});
foo({1,'2',3.0}, {4,'5',6.0});
foo({1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0});
}
ДЕМО 3
Передайте как массив и определите его размер (требуется дополнительная пара скобок):
#include <tuple>
#include <cstddef>
template <std::size_t N>
void foo(const std::tuple<int, char, double> (&a)[N])
{
// a is an array of exactly N std::tuple<int, char, double>
}
int main()
{
foo({{1,'2',3.0}, {4,'5',6.0}});
// ^~~~~~ extra parens ~~~~~^
}
ДЕМО 4
Используйте std::initializer_list
в качестве параметра конструктора (чтобы пропустить лишние скобки):
#include <tuple>
#include <initializer_list>
struct foo
{
foo(std::initializer_list<std::tuple<int, char, double>> li)
{
// li is an initializer list of std::tuple<int, char, double>
}
};
int main()
{
foo{ {1,'2',3.0}, {4,'5',6.0} };
}
ДЕМО 5
person
Piotr Skotnicki
schedule
09.12.2018
int
? Вероятно; вы хотите, чтобы он выводил тип из первого аргумента списка инициализаторов, верно? - person Rakete1111   schedule 09.12.2018int
, как и любое другое. 3 выглядит многообещающе, хотя я не совсем понимаю. - person n. 1.8e9-where's-my-share m.   schedule 09.12.2018{1, '2', 3.0}
нельзя вывести какstd::initializer_list
или массив в стиле C; и не может быть выведено какstd::tuple<T, char, double>
, потому что _4std::initializer_list
5_ само по себе не являетсяstd::tuple
. Я предполагаю, что вам нужно использоватьK
или явно указать тип, вызывающийfoo()
(так чтоfoo<int>( {1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0} );
), или избегать фигурных скобок, по крайней мере, для первого триплета (такfoo(1,'2',3.0, {4,'5',6.0}, {7,'8',9.0})
), чтобы разрешить выводT
. - person max66   schedule 09.12.2018foo(1,'2',3.0, {{4,'5',6.0}, {7,'8',9.0}})
. Таким образом, первая1
выводится какint
, а следующие триплеты - какstd::tuple<int, char, double>const [2]
. - person max66   schedule 09.12.2018foo<int>(...)
идея на самом деле должна бытьfoo<int, int, int>(...)
- person Piotr Skotnicki   schedule 09.12.2018foo<int>()
идеи: требуется дополнительная пара фигурных скобок. - person max66   schedule 09.12.2018foo<int>( {1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0} );
) неверна: также в этом случае требуется дополнительная пара фигурных скобок (так чтоfoo<int>({{1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0}});
), поэтому вы получаетеstd::tuple<T, char, double> const (&arr)[N]
(гдеT
разъясняется иN
выводится). - person max66   schedule 09.12.2018