Created
November 14, 2014 06:14
-
-
Save dmikurube/dd5177db1752b4a53709 to your computer and use it in GitHub Desktop.
This file contains hidden or 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> | |
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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.