how to declare member function using template? (not template class) - c++

I want to declare a template member function in the class.
As i know, we can declare that below case1.
But it will make several classes, but i want to make only one class.
I will not use the template to set member variable. I will use that only for parameter of member function. I want to make template function which can handle vary types in one class instance.
So, is there any way to make template function in the one class?
//case1, standard template function
#include <iostream>
using namespace std;
template <typename T>
class A{
public:
void f(T n){
cout << n <<endl;
}
};
int main(){
A<int> a1;
a1.f(1);
A<float> a2;
a2.f(0.1);
}
//case2, i want to make member function which can receive vary type.
#include <iostream>
using namespace std;
class A{
public:
template <typename T>
void f(T n){
cout << n <<endl;
}
}
int main(){
A a();
a.f(1);
a.f(0.1);
}

Your code works for me after fixing a couple minor typos:
#include <iostream>
using namespace std;
class A{
public:
template <typename T>
void f(T n){
cout << n <<endl;
}
};
int main(){
A a;
a.f(1);
a.f(0.1);
}
$ g++ main.cc
./a.out
1
0.1

Related

How do I format my function to call a templated class?

I'm sure there is a very easy answer, but I can't figure it out. I have written a templated class, but I want to pass that class by reference in a class function that isn't templated. Heres what I have. I get a bunch of errors. All I need to do is figure how to format the way to insert templated class into function, but I'm at a lost. Thank you and sorry if the code doesn't really help you out.
#include <iostream>
using namespace std;
template <typename T>
class Foo {
public:
Foo();
insert(const T& Item)
//And other function, just examples
};
class noFoo(){
void test(Foo <T>& foo);
int i;
int j;
int k
};
template <typename T>
void noFoo::test(Food <T>& foo)}
cout << "hi";
}
int main() {
Foo<char> wr;
test(wr);
return 0;
}
Make test a function template. I also corrected loads of syntax errors for you (class noFoo()?), removed unnecessary code, and ran clang-format for indentation.
#include <iostream>
template <typename T>
class Foo {};
class noFoo
{
public:
template <typename T>
void test(Foo<T> &);
};
template <typename T>
void noFoo::test(Foo<T> &)
{
std::cout << "hi\n";
}
int main()
{
Foo<char> wr;
noFoo{}.test(wr);
}
Since your question is tagged d, here the same code in D.
import std.stdio;
class Foo(T) {};
class noFoo
{
public:
void test(T)(Foo!(T))
{
writeln("hi");
}
};
void main()
{
auto wr = new Foo!char;
(new noFoo).test(wr);
}

undefined reference on Friend template function

I am trying to implement a friend template function over a normal class.
fren.h
#include <iostream>
namespace sn{
class Fren{
private:
int x;
public:
Fren(int y):x(y){
}
template<typename B>
friend void getValue(B& asd);
};
template<typename B>
void getValue(B& asd);
}
fren.cpp
#include "fren.h"
namespace sn{
template<typename B>
void getValue(B& asd){
std::cout<<asd.x<<std::endl;
}
}
main.cpp
#include "fren.h"
int main() {
sn::Fren f(10);
sn::getValue(f);
return 0;
}
I am trying to get the private value x of Fren.
But i get the "undefined reference to" error.
First off, unless there is a solid reason for otherwise, most of this belongs in a single header file. See "Why can templates only be implemented in the header file?" for why.
That said, if you want to use explicit instantiation for your function template, you can. Note the following, which is also more restrictive than your friending. This code only friends the function templates with matching template arguments to Fren:
func.h
#ifndef SAMPLE_FUNC_H
#define SAMPLE_FUNC_H
namespace sn
{
template<class T>
struct Fren;
template<class T>
void getValue(const Fren<T>& s);
template<class T>
struct Fren
{
friend void getValue <>(const Fren<T>&);
Fren() : x(42) {}
private:
int x;
};
} // namespace
#endif
func.cpp
#include "func.h"
#include <iostream>
namespace sn
{
template<class T>
void getValue(const Fren<T>& s)
{
std::cout << s.x << ':' << __PRETTY_FUNCTION__ << '\n';
}
// explicit instantiation here
template void getValue <int> (const Fren<int>&);
}
main.cpp
#include <iostream>
#include <string>
#include "func.h"
int main()
{
sn::Fren<int> s;
sn::getValue(s);
}
Output
42:void sn::func(const S<T> &) [T = int]
Compiled with Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
In short, your code appears to be missing the actual explicit instantiation.

c++ unordered map using templates

I am trying to declare an unordered map using templates in c++. However, as I expect the object to be one of the primitive datatypes I don't want to declare a custom class for only one object.
I've tried using :
template <class T> std::unordered_map<int, T> storedObj;
but I keep getting the error: ‘storedObj’ was not declared in this scope
a code snippet is below
#include<iostream>
#include<unordered_map>
#include<deque>
std::deque<int> freeIds;
template <class T> std::unordered_map<int, T> storedObj;
unsigned static int objIdCount=0;
const unsigned long int MAXID = 1000000000;
Can you please tell me what's wrong? Thanks.
You are doing partial template specialisation here (see http://en.cppreference.com/w/cpp/language/partial_specialization). Probably what you had in mind is a typedef-like construction but that doesn't work with templates.
With partial template specialisation you can (partially) re-implement or re-define a templated type.
One way to achieve your goal could be:
template <class T>
class my_unordered_map :
public std::unordered_map<int, T>
{
};
int main( void ) {
my_unordered_map<float> mf;
return 0;
}
Templates are used for compile-time polymorphism. You cannot instantiate a template-based class without specifying an actual datatype for that template.
A basic way to use templates would be:
#include <iostream>
using namespace std;
template <class T>
class MyClass {
T foo;
public:
MyClass(T bar) {
foo = bar;
}
void print() {
cout << foo;
}
};
int main() {
MyClass<int> c(5);
c.print(); // prints 5
return 0;
}
You can achieve what you're trying to do by extending (deriving) the unordered_map class, like this:
#include <iostream>
#include <unordered_map>
using namespace std;
template <class T>
class MyClass: public unordered_map<int, T> {
// optional extra code here
};
int main() {
MyClass<string> cstring;
cstring[0] = "foo";
cout << cstring[0] << "\n"; // prints "foo"
MyClass<double> cdouble;
cdouble[0] = 3.14; // prints 3.14
cout << cdouble[0];
return 0;
}

C++: Non generic method in generic class?

I am interested in defining a custom method for a generic class for only a particular data type. I am not sure whats a good way to implement it. I won't be able to access class variables if I place it outside the class so I think i can never get it to work that way. If i place it inside the class, its meant to work for any type T and not just the particular type. I have been able to get my code to work the latter way by just defining a generic version of it and sending only that type as input which i m interested in but is there a neater way to accomplish this?
Below is some code to make it clear
#include<iostream>
#include<string>
using namespace std;
template<typename T>
class abc
{
public:
void myvoid();
};
template<typename string>
void abc<string>::myvoid()
{
cout<<"This portion should execute only if an instance of class is called with a string parameter" ;
}
int main()
{
abc<int> int1;
abc<string> string1;
string1.myvoid(); //should work good
int1.myvoid(); //shouldnt execute myvoid
}
You can use static_assert to prevent compilation if the method in question is used with the wrong type:
#include <type_traits> // for std::is_same
template <typename T>
struct Foo
{
void foo() const {}
void bar() const
{
static_assert(std::is_same<T, int>::value, "T is not int");
}
};
int main()
{
Foo<double> fd;
fd.foo(); // OK
//fd.bar(); // ERROR: bar() only works with Foo<int>
Foo<int> fi;
fi.foo(); // OK
fi.bar(); // OK
}
Alternatively, you can use SFINAE to control the types for which the method in question exists.
template <typename T>
class Foo
{
public:
void foo() const {}
template<typename T2 = T,
typename = typename std::enable_if<std::is_same<T, int>::value>::type>
void bar() {}
};
See this related question.
This will give a linker error if you try to call bar() on a non-specialized type. This works on gcc 4.8 (see: http://ideone.com/KbwToR)
#include <iostream>
using namespace std;
struct Foo
{
template <class T>
void bar(T);
};
template<>
void Foo::bar<int>(int i)
{
cout << i << '\n';
}
int main()
{
Foo f;
f.bar(1);
f.bar("Fail!");
return 0;
}

Templates Calling Each Other's Functions

So, I have a fairly simple set of templates that I want to use together, but the compiler keeps telling me that B::a has incomplete type. Everything is forward declared, but it still doesn't work...
#include <iostream>
using namespace std;
template <typename T> class A;
template <typename T> class B;
template <typename T>
class A{
public:
void ATestFunction();
void CallBFunction();
protected:
B<T> b;
};
template <typename T>
class B{
public:
void BTestFunction();
void CallAFunction();
protected:
A<T> a;
};
template <typename T>
void A<T>::ATestFunction(){
cout << "A was used for a function call" << endl;
}
template <typename T>
void B<T>::BTestFunction(){
cout << "B was used for a function call" << endl;
}
template <typename T>
void A<T>::CallBFunction(){
b.BTestFunction();
}
template <typename T>
void B<T>::CallAFunction(){
a.ATestFunction();
}
int main()
{
A<int> dragons;
dragons.CallBFunction();
return 0;
}
I ask this because I had run into some difficulty programming some array type classes that depend on each other (implementing a two dimensional array that can be accessed like this: [][]), but this problem happened and threw a gear in the works. I made this testing program, but it still fails. I've tried both MinGW 4.7.2 and GNU g++ on Linux, and each gave me the same problem.
The core of the issue can be seen in this piece of code:
template <typename T>
class A{
B<T> b;
};
template <typename T>
class B{
A<T> a;
};
C++ is a language with value semantics, that means that B<T> b; represents an object of type B<T> (rather than a reference, like in Java or C# with reference types). That is, A<T> contains a B<T>. Now if you look at the definition of the B template you see that in turn it contains an A<T> sub object. This is basically impossible, as A<T> cannot possibly contain an object that contains A<T>. What would be the size of an A<T> object?
Without knowing the real problem to solve, I won't venture to recommend an approach, but you can consider using pointers (A<T> would contain a pointer to B<T>, not a full B<T> sub object; or similarly, B<T> could contain a pointer to A<T>; or both), or references. But it might also be the case that a deeper redesign could make more sense.
Even if you used pointers, that could not work. That would basically trigger an infinite loop of A´s and B´s being created
A creates B creates A creates B creates A...
this would work.
#include <iostream>
using namespace std;
template<typename T> class A;
template<typename T> class B;
template<typename T>
class A
{
public:
A()
{
b = new B<T>(this);
}
A(B<T>* pb)
{
b = pb;
}
void ATestFunction()
{
cout << "A was used for a function call" << endl;
}
void CallBFunction()
{
b->BTestFunction();
}
protected:
B<T>* b;
};
template<typename T>
class B
{
public:
B()
{
a = new A<T>(this);
}
B(A<T>* pa)
{
a = pa;
}
void BTestFunction()
{
cout << "B was used for a function call" << endl;
}
void CallAFunction()
{
a->ATestFunction();
}
protected:
A<T>* a;
};
int main()
{
A<int> dragons;
dragons.CallBFunction();
B<int> bdragons;
bdragons.CallAFunction();
return 0;
}
or maybe just using static functions
#include <iostream>
using namespace std;
template<typename T> class A;
template<typename T> class B;
template<typename T>
class A
{
public:
static void ATestFunction()
{
cout << "A was used for a function call" << endl;
}
void CallBFunction();
};
template<typename T>
class B
{
public:
static void BTestFunction()
{
cout << "B was used for a function call" << endl;
}
void CallAFunction();
};
template<typename T>
void A<T>::CallBFunction()
{
B<int>::BTestFunction();
}
template<typename T>
void B<T>::CallAFunction()
{
A<int>::ATestFunction();
}
int main()
{
A<int> dragons;
dragons.CallBFunction();
B<int> bdragons;
bdragons.CallAFunction();
return 0;
}