生成一个重载的构造函数集:
#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)
{
}
};
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>;
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
{
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 = {};
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)
{
}
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])
{
}
int main()
{
foo({{1,'2',3.0}, {4,'5',6.0}});
}
DEMO 4
使用 std::initializer_list
作为构造函数参数(省略额外的括号):
#include <tuple>
#include <initializer_list>
struct foo
{
foo(std::initializer_list<std::tuple<int, char, double>> li)
{
}
};
int main()
{
foo{ {1,'2',3.0}, {4,'5',6.0} };
}
DEMO 5
{1,'2',3.0}
中包含不同类型的元素,因此无法将其推断为std :: initializer_list
或C风格数组;也无法将其推断为std :: tuple <T,char,double>
,因为{1,'2',3.0}
本身不是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
推断。 - max66foo(1,'2',3.0, {{4,'5',6.0}, {7,'8',9.0}})
。因此,第一个1
被推断为int
,接下来的三元组被推断为std::tuple<int, char, double>const [2]
。 - max66