c++ unordered map using templates - 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;
}

Related

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

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

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);
}

Templated class member VS Nested class forward declaration

Good evening everyone!
I'm stuck with an itchy problem. Say I have the following code :
#include <iostream>
template <class T>
struct MyTemplate {
int _array[sizeof (T)];
} ;
struct MyStruct {
struct MyNestedStruct {
int foo;
} ;
MyTemplate<MyNestedStruct> _nested;
} ;
int main(int, char **) {
return 0;
}
This example snippet compiles fine. What I would like to do is lift the definition of MyNestedStruct out of MyStruct :
#include <iostream>
template <class T>
struct MyTemplate {
int _array[sizeof (T)];
} ;
struct MyStruct {
struct MyNestedStruct;
MyTemplate<MyNestedStruct> _nested;
} ;
struct MyStruct::MyNestedStruct {
int foo;
} ;
int main(int, char **) {
return 0;
}
Of course this one doesn't compile since I'm requesting the size of a partially declared type (error: invalid application of ‘sizeof’ to incomplete type ‘MyStruct::MyNestedStruct’).
My real use case does need sizeof, but will also use several MyNestedClass-like template parameters in that fashion, each fully declared with constructors and the like. For this reason I don't want MyClass to get bloated. Can I do anything about it, or will I have to resort to an external scope (namespace) to put my "inner" classes in ?
Unless...
struct MyStruct {
#include "MyNestedStruct.h" // Dirty preprocessor to the rescue !
MyTemplate<MyNestedStruct> _nested;
} ;
Ugh.
Essentially we need to defer template instantiation of MyTemplate since that's the one that requires T to be complete. The trick I can see to do that here is to templatize MyStruct.
template <typename T>
struct MyTemplate {
int _array[sizeof(T)];
};
template <typename Dummy = void>
struct MyStruct {
struct MyNestedStruct;
MyTemplate<MyNestedStruct> _nested;
};
template <typename Dummy>
struct MyStruct<Dummy>::MyNestedStruct {
int foo;
};
int main() {}
Now we've deferred the instantiation of MyStruct, but we need to use MyStruct<> instead. If that's unsatisfactory, then just provide a type alias.
#include <iostream>
template <typename T>
struct MyTemplate {
int _array[sizeof(T)];
};
template <typename Dummy = void>
struct MyStructImpl {
struct MyNestedStruct;
MyTemplate<MyNestedStruct> _nested;
};
template <typename Dummy>
struct MyStructImpl<Dummy>::MyNestedStruct {
int foo;
};
using MyStruct = MyStructImpl<>;
int main() {
MyStruct s;
std::cout << sizeof(s._nested._array) << std::endl;
}
Prints 16.
Note: you could also to hide MyStructImpl in a detail namespace or something similar.

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;
}

Determine if template argument is a pointer

Suppose we have template class
template <typename T>
class MyTem{
public:
bool is_T_Pointer(){
<...>
}
};
class Cls : MyTem<Cls>{
<...>
};
int main(void){
Cls* classOnHeap = new Cls(); /* T is pointer */
Cls classOnStack; /* T is not pointer */
<...>
}
I know this is a bad example but if someone could help me find out if T is pointer from template class that would be great.
Remember we have inheritance with template of same class as base class.
Doesn't have to be complete implementation, a vague technique will be enough
You should employ partial specialization here:
template<class T>
class A
{
public:
A() {}
};
template<class T>
class A<T*>
{
public:
A(int) {}
};
Then the following will not compile, because compiler is forced to choose pointer version of template and there is no default constructor:
A<char*> a;
this does compile:
A<char> a;
If the compiler supports C++11 use std::is_pointer:
#include <iostream>
#include <type_traits>
template <typename T>
class MyTem
{
public:
static const bool IS_POINTER = std::is_pointer<T>::value;
};
int main()
{
std::cout << MyTem<char*>::IS_POINTER << "\n";
std::cout << MyTem<char>::IS_POINTER << "\n";
return 0;
}
See demo http://ideone.com/Mo394 .