Is it implemented already, because this does not compile: (using gcc 4.7.2)
template <typename... Ts>
struct Foo {
int foo() {
return 0;
}
};
template <>
struct Foo<int x, int y> {
int foo() {
return x * y;
}
};
int main()
{
Foo<2, 3> x;
cout << x.foo() << endl; //should print 6
}
With the variadic templates feature, you can define class or function templates that have any number (including zero) of parameters. To achieve this goal, this feature introduces a kind of parameter called parameter pack to represent a list of zero or more parameters for templates.
A variadic template is a class or function template that supports an arbitrary number of arguments. This mechanism is especially useful to C++ library developers: You can apply it to both class templates and function templates, and thereby provide a wide range of type-safe and non-trivial functionality and flexibility.
Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue.
variadic (not comparable) (computing, mathematics, linguistics) Taking a variable number of arguments; especially, taking arbitrarily many arguments.
You are making a few mistakes. The primary template expects types, not integral constants. You also try to instantiate the template with integral constants, but your partial specialization uses types.
This is closer:
#include <iostream>
template <int... Ts>
struct Foo {
int foo() {
return 0;
}
};
template <>
struct Foo<3, 2> {
const int x = 3;
const int y = 2;
int foo() {
return x * y;
}
};
int main()
{
Foo<2, 3> x;
std::cout << x.foo() << std::endl; //should print 6
}
But this is not really what we want, right? And it is also clumsy.
#include <iostream>
template<typename Acc, typename... Rest>
struct accum_help; // primary
template<typename Acc, typename F, typename... Rest>
struct accum_help<Acc, F, Rest...> {
typedef typename accum_help<
std::integral_constant<typename Acc::value_type,
Acc::value * F::value>, Rest...
>::type type;
};
template<typename Acc>
struct accum_help<Acc> {
typedef Acc type;
};
// peek into the first argument to avoid summing empty sequences and
// get the right type
template<typename X, typename... Integrals>
struct accum {
typedef typename accum_help<
std::integral_constant<typename X::value_type, 1>, X, Integrals...
>::type type;
};
int main()
{
std::cout << accum< std::integral_constant<int, 2>, std::integral_constant<int, 3> >::type::value << std::endl; //should print 6
}
A simpler variant handling only int:
template <int...>
struct accum2_help;
template <int Acc, int X, int... Rest>
struct accum2_help<Acc, X, Rest...> {
static const int value = accum2_help< Acc * X, Rest...>::value;
};
template <int Acc>
struct accum2_help<Acc> {
static const int value = Acc;
};
// again don't accept empty packs
template <int T, int... Ts>
struct accum2 {
static const int value = accum2_help<1, T, Ts...>::value;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With