Created
September 30, 2012 04:27
-
-
Save TheTomster/3805835 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
// This file is kind of crazy because of the names, but here goes... | |
// Foo is our template class. It holds a thing of type T, called the_t. | |
// When someone creates a new Foo, it creates a T with T::T() and saves it. | |
// Then, someone can call Foo.foobar and pass us an "uber" of type U. | |
// The uber needs to have a spork function, which accepts a T. | |
// the type signature looks like this: | |
// void U::spork(T); | |
template <class T> | |
class Foo { | |
private: | |
T the_t; | |
public: | |
template <class U> | |
void foobar(U& uber) { | |
uber.spork(the_t); | |
} | |
}; | |
// structs are just like classes in c++, but things are public by default. | |
struct Bar { | |
int count; | |
// initialization list here... they probably glazed over it. basically it's | |
// crazy syntax that sets count to 0. Ask me sometime if you're curious about | |
// these :-) | |
Bar() : count(0) {} | |
}; | |
struct Potato { | |
int increment; | |
Potato(int i) | |
: increment(i) { } | |
// notice that i'm using a reference here! this is very important because the | |
// default behavior is to create a copy of b, modify it, and then throw it | |
// away. we want to actually change whatever the caller gives us. You could | |
// also use pointers for this but pointers suck. | |
void spork(Bar& b) { | |
b.count += increment; | |
std::cout << b.count << std::endl; | |
} | |
}; // don't forget these asshole semicolons on class / struct | |
struct Koala { | |
int increment; | |
Koala(int i) | |
: increment(i) { } | |
void spork(Bar& b) { | |
b.count -= increment; | |
std::cout << b.count << std::endl; | |
} | |
}; | |
int main() { | |
// so here we create a Foo<Bar> called f. So anywhere up in Foo where it | |
// says T, is going to be a Bar. f.the_t has a counter set to 0. | |
Foo<Bar> f; | |
// Now we set up a Potato, and set Potato's increment to 12. | |
Potato p(12); | |
// Now the magic happens. We call f.foobar(p). | |
// Let's look at the types here. | |
// f is a Foo<Bar> | |
// p is a Potato | |
// So if we fill in those types and variable names in f.foobar... the source | |
// looks like this: | |
// foobar(Potato uber) { // uber is a copy of the p we passed in | |
// uber{Potato}.spork(the_t{Bar}); // I put the type in {} | |
// } | |
// At compile time, the compiler checks to make sure these types make sense. | |
// It asks: Does Potato have a function "void spork(Bar)"? It does! So it | |
// generates code for that and the compilation proceeds. | |
f.foobar(p); | |
f.foobar(p); | |
f.foobar(p); | |
// The generic-ness comes in when we make a new thing that fits the "U" type | |
// in Foo's templates. Here I make a Koala that subtracts from Bar's counter | |
// instead of adding. | |
Koala k(3); | |
f.foobar(k); | |
f.foobar(k); | |
f.foobar(k); | |
// I hope that all makes sense! It's a shitty example because I'm just | |
// derping around to see if this works, but it does! | |
// | |
// Here's the output. You see the result is that f.the_t's counter gets | |
// incremented 12 at a time, and then decremented 3 at a time! IT'S WORKING! | |
// | |
// Tom@Squidward ~/sandbox | |
// $ ./crazy_names.exe | |
// 12 | |
// 24 | |
// 36 | |
// 33 | |
// 30 | |
// 27 | |
// | |
// In summary: lol c++ | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template<class T> | |
class Foo { | |
private: | |
T the_t; | |
public: | |
T get_the_t(); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
class Waffle { | |
public: | |
void fooderate() { | |
using namespace std; | |
cout << "I am a waffle!" << endl; | |
} | |
}; | |
template<class Breakfast> | |
void fooderator(Breakfast& f) { | |
f.fooderate(); | |
} | |
int main() { | |
Waffle w; | |
fooderator(w); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment