Skip to content

Instantly share code, notes, and snippets.

@kjelloh
Last active December 11, 2016 11:05
Show Gist options
  • Save kjelloh/d51b6961f2b0f93829fca7b054c98e62 to your computer and use it in GitHub Desktop.
Save kjelloh/d51b6961f2b0f93829fca7b054c98e62 to your computer and use it in GitHub Desktop.
//
// main.cpp
// MydecltypeMetaFunctions
//
// Created by Kjell-Olov Högdahl on 2016-12-10.
//
/*
Program Output:
meta_f(tag_1) type_name=type_1
meta_f(tag_2) type_name=type_2
c1.type_name=type_1
c2.type_name=type_2
template_meta_f<tag_1> type_name = type_1
template_meta_f<tag_2> type_name = type_2
specialized_meta_f<tag_1> type_name = type_1
specialized_meta_f<tag_2> type_name = type_2
*/
#include <iostream>
#include <string>
struct tag_1 {};
struct tag_2 {};
auto meta_f(const tag_1&) {
// Locally defined return type (exposed through auto)
struct type_1 {
const std::string type_name = "type_1";
};
return type_1();
}
auto meta_f(const tag_2&) {
// Locally defined return type (exposed through auto)
struct type_2 {
const std::string type_name = "type_2";
};
return type_2();
}
template <typename T>
struct template_meta_f {
using type = decltype(meta_f(T()));
};
template <typename T>
struct specilized_meta_f {}; // Primary template
template <>
struct specilized_meta_f<tag_1> {
using type = decltype(meta_f(tag_1()));
};
template <>
struct specilized_meta_f<tag_2> {
using type = decltype(meta_f(tag_2()));
};
decltype(meta_f(tag_1())) c1;
decltype(meta_f(tag_2())) c2;
int main(int argc, const char * argv[]) {
// Use type returned by compiler selected meta_f function
std::cout << "\nmeta_f(tag_1) type_name=" << decltype(meta_f(tag_1()))().type_name;
std::cout << "\nmeta_f(tag_2) type_name=" << decltype(meta_f(tag_2()))().type_name;
// Use variables of type returned by compiler selected meta_f function
std::cout << "\nc1.type_name=" << c1.type_name;
std::cout << "\nc2.type_name=" << c2.type_name;
// Use template type (defined as type returned by compiler selected meta_f function)
std::cout << "\ntemplate_meta_f<tag_1> type_name = " << template_meta_f<tag_1>::type().type_name;
std::cout << "\ntemplate_meta_f<tag_2> type_name = " << template_meta_f<tag_2>::type().type_name;
// Use "old" template deduction
std::cout << "\nspecialized_meta_f<tag_1> type_name = " << specilized_meta_f<tag_1>::type().type_name;
std::cout << "\nspecialized_meta_f<tag_2> type_name = " << specilized_meta_f<tag_2>::type().type_name;
std::cout << '\n';
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment