Вот и мы!
Прежде всего, код немного запутан - мне нужно накапливать значения аргументов по ходу работы, и единственный способ, которым я мог придумать (по крайней мере, в C ++ 03), - передать непосредственные индексы, установленные вокруг как массивы.
Я проверил это на G ++ 4.5.1 (Windows / MinGW) и подтверждаю, что на -O3 вызов:
s[1][2][3][4];
дает тот же код ассемблера, что и:
s(1,2,3,4);
Так что - никаких затрат времени выполнения, если ваш компилятор умен с оптимизацией. Хорошая работа, команда GCC!
Вот код:
#include <iostream>
template<typename T, unsigned N, unsigned Count>
struct PartialResult
{
static const int IndicesRemembered = Count-1-N;
T& t;
int args[IndicesRemembered];
PartialResult(T& t, int arg, const int* rest) : t(t) {
for (int i=0; i<IndicesRemembered-1; ++i) {
args[i] = rest[i];
}
if (IndicesRemembered>0) args[IndicesRemembered-1] = arg;
}
PartialResult<T, N-1, Count> operator[](int k) {
return PartialResult<T, N-1, Count>(t, k, args);
}
};
template<typename T, unsigned Count>
struct PartialResult<T, 0, Count>
{
static const int IndicesRemembered = Count-1;
T& t;
int args[IndicesRemembered];
PartialResult(T& t, int arg, const int* rest) : t(t) {
for (int i=0; i<IndicesRemembered-1; ++i) {
args[i] = rest[i];
}
if (IndicesRemembered>0) args[IndicesRemembered-1] = arg;
}
void operator[](int k) {
int args2[Count];
for (int i=0; i<Count-1; ++i) {
args2[i] = args[i];
}
args2[Count-1] = k;
t(args2);
}
};
template<typename T, unsigned Count>
struct InitialPartialResult : public PartialResult<T, Count-2, Count> {
InitialPartialResult(T& t, int arg)
: PartialResult<T, Count-2, Count>(t, arg, 0) {}
};
struct C {
void operator()(const int (&args)[4]) {
return operator()(args[0], args[1], args[2], args[3]);
}
void operator()(int a, int b, int c, int d) {
std::cout << a << " " << b << " " << c << " " << d << std::endl;
}
InitialPartialResult<C, 4> operator[](int m) {
return InitialPartialResult<C, 4>(*this, m);
}
};
А если серьезно, пожалуйста, не используйте это и просто придерживайтесь operator()
. :) Ура!