c++ recursive function with calling a class using a templatefunction - c++

I would like to have a function, that counts a value down to zero. in addition, i would like to call some code which class is passed as a template parameter.
but this code doesn't work. please can someone help me?
thanks a lot.
The error message is:
"function template partial specialization 'foo<0, T>' is not allowed"
class Hello_World
{
public:
void hello(size_t number){
cout << "hello " << number << endl;
}
};
template<size_t SIZE, class T>
void foo()
{
T t;
t.hello(SIZE);
foo<SIZE-1, Hello_World>();
}
template<class T>
void foo<0,T>()
{
cout << "end." << endl;
}
int main()
{
foo<4,Hello_World>();
}

You can't partially specialize template functions. Wrap it in a class:
template <size_t SZ, typename T >
struct foo_impl
{
static void call()
{
T().hello(SZ);
foo_impl<SZ-1, T>::call();
}
};
template < typename T >
struct foo_impl<0,T>
{
// you get the idea...
};
template <size_t SZ, typename T >
void foo() { foo_impl<SZ,T>::call(); }

You cannot partially specialize a function template. However, you can partially specialize a functor (that basically acts like a function):
#include <iostream>
template<size_t SIZE, class T>
struct foo {
void operator()(){ foo<SIZE-1, T>()(); }
};
template<class T>
struct foo<0,T> {
void operator()(){ std::cout << "end." <<std::endl; }
};
int main(){
foo<3,int>()();
}

Related

How can I declare a new variable of the same class but with different template parameters in c++?

I want to write a template function that, given any class, will instantiate a new one but the template param is 1. I would like to do something like this:
template <uint COUNT>
class Foo {
using MY_NAME = Foo;
int data[COUNT];
void print();
}
template <class T>
void my_function(T in) {
auto x = in::MY_NAME<1>; // This somehow makes a XXX<whatever> into an XXX<1>.
x.print();
}
my_function(Foo<5>); // This should call Foo<1>.print();
I want to use templates or using or something so that whatever input class I'm receiving, I make a new instance that is the same class but with a different template parameter.
Can this be done? It's all known at compile time so it seems like there ought to be a way to do it.
Use a template template parameter. In this case, you would want to specify a non-type template parameter for the inner tempalte. That would look like
template <std::size_t COUNT>
struct Foo {
using MY_NAME = Foo;
int data[COUNT];
void print() { std::cout << "COUNT: " << COUNT; }
};
template <template<std::size_t> typename class_t, std::size_t N>
void my_function(class_t<N>) {
auto x = class_t<1>{}; // This somehow makes a XXX<whatever> into an XXX<1>.
x.print();
}
int main()
{
my_function(Foo<5>{}); // This should call Foo<1>.print();
}
and it outputs
COUNT: 1
as seen in this live example.
I'm not sure it's possible to make the using declaration do what you want it to, making MY_NAME refer to the injected template name Foo instead of the injected class name Foo<COUNT>. However you can make MY_NAME be itself a template:
#include <iostream>
template <uint COUNT>
class Foo {
public:
template<uint C>
using MY_NAME = Foo<C>;
int data[COUNT];
void print() { std::cout << COUNT << '\n'; }
};
template <class T>
void my_function(T in) {
auto x = typename T::MY_NAME<1>{}; // Typename keyword is necessary here
x.print();
}
int main()
{
my_function(Foo<5>{}); // Prints 1
my_function(Foo<7>{}); // Prints 1
}
Demo here.
So now for any class template Bar that exports its name via using MY_NAME you can pass it to my_function to call Bar<1>.print().
Not sure what you need it for but the syntax you're looking could be this:
#include <array>
#include <iostream>
#include <utility>
template<std::size_t N>
struct Foo
{
// initialized array
std::array<int,N> data {};
// output all the values in the array
void print()
{
for (const int value : data) std::cout << value << " ";
}
};
template<typename type_t>
void my_function(const type_t& value)
{
std::cout << "my_function(" << value << ")\n";
// create a temporary and print it.
Foo<1>().print();
}
int main()
{
int v{ 5 };
my_function<int>(v);
}

Nested template C++

I have a template class of the form:
template<typename ContainerType>
class ConfIntParamStat {
public:
typedef typename ContainerType::Type Type;
...
private:
void sample(int iteration) {...}
}
I would like to create a specific version of the function sample for the case when ContainerType is a Vector. Where Vector itself is a template class, but I do not know which type of values this Vector holds.
My intuition was to create this in the header file:
template<typename Type>
ConfIntParamStat<Vector<Type> >::sample(int iteration) {
...
}
But it does not compile, and the error from clang is:
error: nested name specifier 'ConfIntParamStat<Vector<Type> >::' for declaration does not refer into a class, class template or class template partial specialization
Is it possible using another syntax ?
If you didnt want to specialize the template and were looking for a member only specialization try the following
#include <iostream>
#include <vector>
using namespace std;
template <typename ContainerType>
class Something {
public:
void do_something(int);
template <typename Which>
struct do_something_implementation {
void operator()() {
cout << "general implementation" << endl;
}
};
template <typename Which>
struct do_something_implementation<vector<Which>> {
void operator()() {
cout << "specialized implementation for vectors" << endl;
}
};
};
template <typename ContainerType>
void Something<ContainerType>::do_something(int) {
do_something_implementation<ContainerType>{}();
}
int main() {
Something<double> something;
something.do_something(1);
return 0;
}
If your intent is to specialize a function, I would just overload the function like so
#include <iostream>
#include <vector>
using namespace std;
template <typename ContainerType>
class Something {
public:
void do_something(int);
template <typename Type>
void do_something(const vector<Type>&);
};
template <typename ContainerType>
void Something<ContainerType>::do_something(int) {
cout << "Called the general method for do_something" << endl;
}
template <typename ContainerType>
template <typename Type>
void Something<ContainerType>::do_something(const vector<Type>&) {
cout << "Called the specialised method" << endl;
}
int main() {
vector<int> vec{1, 2, 3};
Something<double> something;
something.do_something(1);
something.do_something(vec);
return 0;
}
This is mostly why full/explicit function template specializations are not required. Overloading allows for almost the same effects!
Note This is a great article related to your question! http://www.gotw.ca/publications/mill17.htm
You could make use of the overloading mechanism and tag dispatch:
#include <vector>
template <class T>
struct Tag { };
template<typename ContainerType>
class ConfIntParamStat {
public:
typedef typename ContainerType::value_type Type;
//...
// private:
void sample(int iteration) {
sample_impl(Tag<ContainerType>(), iteration);
}
template <class T>
void sample_impl(Tag<std::vector<T> >, int iteration) {
//if vector
}
template <class T>
void sample_impl(Tag<T>, int iteration) {
//if not a vector
}
};
int main() {
ConfIntParamStat<std::vector<int> > cips;
cips.sample(1);
}
As skypjack mentioned this approach has a little draw when using const. If you are not using c++11 (I suspect you dont because you use > > syntax for nested templates) you could workaround this as follows:
#include <iostream>
#include <vector>
template <class T>
struct Tag { };
template <class T>
struct Decay {
typedef T Type;
};
template <class T>
struct Decay<const T> {
typedef T Type;
};
template<typename ContainerType>
class ConfIntParamStat {
public:
typedef typename ContainerType::value_type Type;
//...
// private:
void sample(int iteration) {
sample_impl(Tag<typename Decay<ContainerType>::Type>(), iteration);
}
template <class T>
void sample_impl(Tag<std::vector<T> >, int iteration) {
std::cout << "vector specialization" << std::endl;
}
template <class T>
void sample_impl(Tag<T>, int iteration) {
std::cout << "general" << std::endl;
}
};
int main() {
ConfIntParamStat<const std::vector<int> > cips;
cips.sample(1);
}
Another way to approach this is composition.
The act of adding a sample can be thought of as a component of the implementation of the class. If we remove the implementation of adding a sample into this template class, we can then partially specialise only this discrete component.
For example:
#include <vector>
//
// default implementation of the sample component
//
template<class Outer>
struct implements_sample
{
using sample_implementation = implements_sample;
// implements one function
void sample(int iteration) {
// default actions
auto self = static_cast<Outer*>(this);
// do something with self
// e.g. self->_samples.insert(self->_samples.end(), iteration);
}
};
// refactor the container to be composed of component(s)
template<typename ContainerType>
class ConfIntParamStat
: private implements_sample<ConfIntParamStat<ContainerType>>
{
using this_class = ConfIntParamStat<ContainerType>;
public:
// I have added a public interface
void activate_sample(int i) { sample(i); }
// here we give the components rights over this class
private:
friend implements_sample<this_class>;
using this_class::sample_implementation::sample;
ContainerType _samples;
};
//
// now specialise the sample function component for std::vector
//
template<class T, class A>
struct implements_sample<ConfIntParamStat<std::vector<T, A>>>
{
using sample_implementation = implements_sample;
void sample(int iteration) {
auto self = static_cast<ConfIntParamStat<std::vector<T, A>>*>(this);
// do something with self
self->_samples.push_back(iteration);
}
};
int main()
{
ConfIntParamStat< std::vector<int> > cip;
cip.activate_sample(1);
cip.activate_sample(2);
}

Overload recursively based on template parameter

When playing around with good ol' c++ I started wondering whether it is possible to overload a template function based on an enclosing template. At the first layer this looks achievable, however, how can this be done recursively? So that the below pseudo-c++ code
#include <iostream>
#include <vector>
#include <map>
template <typename T> void magic(){
std::cout << "Called magic<T>" << std::endl;
}
template <typename std::vector<T> > void magic(){
std::cout << "Called magic<std::vector<T> >" << std::endl;
magic<T>();
}
template <typename std::map<T,U> > void magic(){
std::cout << "Called magic<std::map<T,U> >" << std::endl;
magic<T>();
magic<U>();
}
int main() {
magic<std::vector<std::map<std::string,std::vector<int> > > >();
}
yields something like:
Called magic<std::vector<T> >
Called magic<std::map<T,U> >
Called magic<T>
Called magic<std::vector<T> >
Called magic<T>
In principle this does not look like it should be impossible because all the type info is available at compile time. The compiler could easily create all required functions since the recursion is bound to stop. And thus the question: Is this possible? If so, how?
Simple specialization should do the trick, but bear in mind that you cannot specialize function templates partially, so you'll need an intermediate class template:
template <typename> void magic();
template <typename T>
struct Impl
{
static void f() { std::cout << "Primary template\n"; }
};
template <typename T, typename A>
struct Impl<std::vector<T, A>>
{
static void f() { std::cout << "A vector\n"; magic<T>(); }
};
template <typename K, typename T, typename P, typename A>
struct Impl<std::map<K, T, P, A>>
{
static void f() { std::cout << "A map\n"; magic<K>(); magic<T>(); }
};
template <typename T> void magic() { Impl<T>::f(); }
You need partial template specialization, that is a template specialization which itself is a template again.
That is not possible with function templates but it is with classes. So the workaround is to create a class template (here called Magic) with the specializations. Within that class, a simple (non-template) function is called.
Then, a function magic forwards to that class in order to hide that "hack":
Live demo of this code snippet
#include <iostream>
#include <vector>
#include <map>
// Forward declaration of the magic function:
template <typename> void magic();
// General case:
template <typename T>
struct Magic {
static void m(){
std::cout << "Called magic<T>" << std::endl;
}
};
// Vector case:
template <typename T>
struct Magic<std::vector<T> > {
static void m(){
std::cout << "Called magic<std::vector<T> >" << std::endl;
magic<T>();
}
};
// Map case:
template <typename T, typename U>
struct Magic<std::map<T,U> > {
static void m(){
std::cout << "Called magic<std::map<T> >" << std::endl;
magic<T>();
magic<U>();
}
};
// Implementation of the magic function:
template <typename T>
void magic() {
std::cout << "Forwarding..." << std::endl;
Magic<T>::m();
}
int main() {
magic<std::vector<std::map<std::string,std::vector<int> > > >();
}

template class overloading

I am wondering how to overload a template class. If I have the following class. I want to create different function for different type of T.
template <class T>
class A {
T data;
public:
void print_data(void);
}
if the T is double type, I need a function like following pseudo code:
template <class T>
void A<double>::print_data(){
printf("%g",date);
}
if the T is complex type, I need it work like this:
template <class T>
void A< complex<double> >::print_data(){
printf("%g+%gi",data.real(),date.imag());
}
How should I achieve this goal. Thank you!
I find a solution but I think it is not very good. The basic idea is using a input parameter for overloading.
template <class T>
class A {
public:
T data;
void print_data(double);
void print_data(complex<T>);
}
template <class T>
void A<T>::print_data(double){
printf("%g",date);
}
template <class T>
void A<T>::print_data(complex<T>){
printf("%g+%gi",data.real(),date.imag());
}
int main(void)
{
//just demonstrate the idea, may not work
A<double> ddata;
A<complex> cdata;
ddata.data = 2.0;
cdata.data = complex(1,2);
ddata->print_data(ddata);
cdata->print_data(cdata);
return 0;
}
anyone have better solution?
Just specialize your template functions for concrete types:
template <>
void A<double>::print_data()
{
std::cout << data << std::endl;
}
template<>
void A<complex<double> >::print_data(){
std::cout << data.real() << "+" << data.imag() << std::endl;
}

Is it possible to write specialization for member function of a template class?

template <class T, bool flag>
class A
{
//...
void f()
{
std::cout << "false" << std::endl;
}
//...
};
template<class T>
void A<T, true>::f<T, true>()
{
std::cout << "true" << std::endl;
}
The code above is wrong and don't compile, but you get the idea of what I'm going to do. So how should I do that?
You can't specialize just one method of a class. Usually you can solve that with a template nested class on the same T.
template <class T, bool flag>
class A
{
//...
template <class Q, bool flag>
class F_Helper
{
void operator()()
{
std::cout << "false" << std::endl;
}
};
template <class Q>
class F_Helper<Q, true>
{
void operator()()
{
std::cout << "true" << std::endl;
}
};
F_Helper<T> f;
//...
};
Obviously a bit more boilerplate is needed if you do need access to the enclosing class' this pointer.
Contrary to what the other answers say, you can specialize a member function of a class template. But you need to provide all template arguments
template<>
void A<int, true>::f()
{
std::cout << "true" << std::endl;
}
What you try is not valid:
template<typename T>
void A<T, true>::f()
{
std::cout << "true" << std::endl;
}
Partially specializing a member of a class template for particular arguments of that class template is not valid, so that means "define the member function 'f' of a partial specialization of A for <T, true>". Because there is no such partial specialization, the compiler will error out.
If you cannot provide all arguments, you can overload f as follows
template <class T, bool flag>
class A
{
template<typename, bool> struct params { };
void f()
{
f(params<T, flags>());
}
template<typename U>
void f(params<U, true>) {
std::cout << "true" << std::endl;
}
template<typename U, bool flag1>
void f(params<U, flag1>) {
std::cout << "dunno" << std::endl;
}
};
You can specialize whole template class - Ideone link
#include <iostream>
template <class T, bool flag>
class A
{
//...
void f()
{
std::cout << "false" << std::endl;
}
//...
};
template<class T>
class A<T, true>
{
//...
void f()
{
std::cout << "true" << std::endl;
}
//...
};
You need to specialize the whole class:
#include <iostream>
template <class T, bool flag>
class A
{
public:
void f()
{
std::cout << "false" << std::endl;
}
};
template<class T>
class A<T,true>
{
public:
void f()
{
std::cout << "true" << std::endl;
}
};
void main()
{
A<int, false> a;
a.f();
A<int, true> b;
b.f();
}