Skip to content

Instantly share code, notes, and snippets.

@dmikurube
Created November 14, 2014 06:14
Show Gist options
  • Save dmikurube/dd5177db1752b4a53709 to your computer and use it in GitHub Desktop.
Save dmikurube/dd5177db1752b4a53709 to your computer and use it in GitHub Desktop.
#include <iostream>
enum EntryIds {
Entry1,
NumberOfEntries
};
class EntryBase {
public:
EntryBase() : entry_id_(NumberOfEntries) {}
EntryBase(int entry_id) : entry_id_(entry_id) {}
private:
int entry_id_;
};
template <int entry_id>
struct EntryT : public EntryBase {
EntryT() : EntryBase(entry_id) {}
};
template <typename T>
struct EntryTypeT {
typedef T type;
};
#ifdef DECLARE_ENTRY_
#error "The macro DECLARE_ENTRY_ is duplicated."
#else
#define DECLARE_ENTRY_(NAME, \
TYPE, \
DEFAULT_VALUE) \
template <> \
struct EntryT<NAME> { \
typedef TYPE Type; \
static const int ID = NAME; \
static const Type getDefaultValue() { return DEFAULT_VALUE; } \
}
#endif // DECLARE_ENTRY_
DECLARE_ENTRY_(Entry1, unsigned int, 1024);
void getRawValue(unsigned int* out) {
*out = 42;
}
template <int entry_id>
typename EntryTypeT<typename EntryT<entry_id>::Type>::type
getValue() {
typedef EntryT<entry_id> Entry;
typedef typename EntryTypeT<Entry::Type>::type EntryType;
EntryType value = Entry::getDefaultValue();
getRawValue(&value);
return value;
}
int main() {
unsigned int value = getValue<Entry1>();
std::cout << value << std::endl;
return 0;
}
@dmikurube
Copy link
Author

cl compiles it.

g++ fails.
template_test.cpp: In function 'typename EntryTypeT<typename EntryT<entry_id>::Type>::type getValue()':
template_test.cpp:50:42: error: type/value mismatch at argument 1 in template parameter list for 'template struct EntryTypeT'
template_test.cpp:50:42: error:   expected a type, got 'Entry:: Type'
template_test.cpp:50:59: error: invalid type in declaration before ';' token
template_test.cpp: In function 'typename EntryTypeT<typename EntryT<entry_id>::Type>::type getValue() [with int entry_id = 0, typename EntryTypeT<typename EntryT<entry_id>::Type>::type = unsigned int]':
template_test.cpp:57:41:   instantiated from here
template_test.cpp:52:3: error: invalid conversion from 'EntryType* {aka int_}' to 'unsigned int_' [-fpermissive]
template_test.cpp:42:6: error:   initializing argument 1 of 'void getRawValue(unsigned int*)' [-fpermissive]

clang++ fails.
template_test.cpp:50:31: error: template argument for template type parameter must be a type; did you forget 'typename'?
  typedef typename EntryTypeTEntry::Type::type EntryType;
                              ^
template_test.cpp:21:20: note: template parameter is declared here
template
                   ^
template_test.cpp:50:45: error: expected a qualified name after 'typename'
  typedef typename EntryTypeTEntry::Type::type EntryType;
                                            ^
template_test.cpp:50:49: error: expected ';' at end of declaration
  typedef typename EntryTypeTEntry::Type::type EntryType;
                                                ^
                                                ;
template_test.cpp:51:3: error: use of undeclared identifier 'EntryType'; did you mean 'EntryTypeT'?
  EntryType value = Entry::getDefaultValue();
  ^~~~~~~~~
  EntryTypeT
template_test.cpp:22:8: note: 'EntryTypeT' declared here
struct EntryTypeT {
       ^
template_test.cpp:51:3: error: unknown type name 'EntryType'; did you mean 'EntryBase'?
  EntryType value = Entry::getDefaultValue();
  ^~~~~~~~~
  EntryBase
template_test.cpp:8:7: note: 'EntryBase' declared here
class EntryBase {
      ^
template_test.cpp:52:3: error: no matching function for call to 'getRawValue'
  getRawValue(&value);
  ^~~~~~~~~~~
template_test.cpp:42:6: note: candidate function not viable: no known conversion from 'EntryBase ' to 'unsigned int *'
      for 1st argument
void getRawValue(unsigned int
out) {
     ^
6 errors generated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment