Skip to content

Instantly share code, notes, and snippets.

@jefftrull
Created August 23, 2012 21:12
Show Gist options
  • Save jefftrull/3441824 to your computer and use it in GitHub Desktop.
Save jefftrull/3441824 to your computer and use it in GitHub Desktop.
Exploring class specialization, member function specialization, and overloading; and how they interact
// experiments for varying class member function behavior with
// class template args, member template args, and member function overloads
// Jeff Trull 2012-08-23
#include <string>
#include <iostream>
template<typename T>
struct Foo {
void invariant() {
std::cout << "this function does not change\n";
}
// behavior changes by varying the member function template arg
template<typename U>
void function_template() {
std::cout << "unspecialized function_template\n";
}
// behavior changes by varying the member function template arg
void function_specialized_by_class_template_parameter() {
std::cout << "unspecialized function_specialized_by_class_template_parameter\n";
}
void overloaded_function(int) {
std::cout << "overloaded function for int arg; invariant with class template arg\n";
}
void overloaded_function(std::string) {
std::cout << "overloaded function for string arg; invariant with class template arg\n";
}
};
// this does not work because functions must be completely specialized,
// including their enclosing class (if it's a template)
/*
template<typename T>
void Foo<T>::function_template<int> {
std::cout << "function template with int arg\n";
}
template<typename T>
void Foo<T>::function_template<std::string> {
std::cout << "function template with string arg\n";
}
*/
template<>
template<>
void Foo<int>::function_template<int>() {
std::cout << "class template member function template with both int args\n";
}
template<>
template<>
void Foo<std::string>::function_template<int>() {
std::cout << "class template member function template with class=string, function=int arg\n";
}
template<>
template<>
void Foo<int>::function_template<std::string>() {
std::cout << "class template member function template with class=int, function=string arg\n";
}
template<>
template<>
void Foo<std::string>::function_template<std::string>() {
std::cout << "class template member function template with both string args\n";
}
template<>
void Foo<int>::function_specialized_by_class_template_parameter() {
std::cout << "non-template function specialized by class template argument = int\n";
}
template<>
void Foo<std::string>::function_specialized_by_class_template_parameter() {
std::cout << "non-template function specialized by class template argument = string\n";
}
int main() {
std::cout << "int class results:\n";
Foo<int> f;
f.invariant();
f.function_specialized_by_class_template_parameter();
f.function_template<int>();
f.function_template<std::string>();
f.overloaded_function((int)1);
f.overloaded_function(std::string());
std::cout << "\nstring class results:\n";
Foo<std::string> g;
g.invariant();
g.function_specialized_by_class_template_parameter();
g.function_template<int>();
g.function_template<std::string>();
g.overloaded_function((int)1);
g.overloaded_function(std::string());
// finally, a type we haven't provided any specialization for
std::cout << "\ndouble class results:\n";
Foo<double> h;
h.invariant();
h.function_specialized_by_class_template_parameter(); // "unspecialized"
h.function_template<int>(); // "unspecialized"
h.function_template<std::string>(); // "unspecialized"
// but these work fine b/c vary based on argument, not class template arg:
h.overloaded_function((int)1);
h.overloaded_function(std::string());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment