1

Here is the code,

#include<iostream>
using namespace std;

template <typename T>
class TestClass {
  T value;
  enum _SyncType {
    SYNC_TYPE,
    ASYNC_TYPE,
  };

  static const char *const kSyncString[];
};

template <typename T>
const char *const TestClass<T>::kSyncString[] = {
  [TestClass<T>::SYNC_TYPE]  = "sync type",
  [TestClass<T>::ASYNC_TYPE]  = "async type",
};

int main() {
  TestClass<int> test;
  return 0;
}

When I compile it, it reminds

prog.cpp:19:1: error: the value of 'SYNC_TYPE' is not usable in a constant expression
 };
 ^
prog.cpp:8:5: note: 'TestClass<T>::_SyncType SYNC_TYPE' is not const
     SYNC_TYPE,
     ^
prog.cpp:19: confused by earlier errors, bailing out

I think maybe the template doesn't have any instance yet, but how should I write such code?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • `_SyncType` - underscore and upper case on the first and second character (respectively) of name is reserved by standard; use another name. – ikh Mar 19 '15 at 11:00
  • `[TestClass::SYNC_TYPE] = "sync type",` is not a valid c++ syntax – Piotr Skotnicki Mar 19 '15 at 11:03
  • @PiotrS. Well, when I changed `enum` into `static constexpr`, [it works.](http://ideone.com/gytxXp) I think there's a reason or it's compiler bug. (or just compiler extension?) – ikh Mar 19 '15 at 11:04
  • @ikh, yes, it is. And if I replace the template class with a class, it can compile successful, so I think is the template problem. but how could I use in this way? I used the online compiler also have same problem, maybe not compiler problem. – Niklas Wang Mar 19 '15 at 11:08
  • @PiotrS. and OP, [it seems just a GNU extension.](http://stackoverflow.com/questions/13477281/initializing-an-array-of-ints?lq=1) (online compilers usually uses gcc or clang >o<) I guess this problem happens because of the extension's defeat. – ikh Mar 19 '15 at 11:11
  • @ikh. Seems replace this kind of syntax is a better choice, thanks! – Niklas Wang Mar 19 '15 at 11:17
  • @ikh this is a feature of the C99 standard, I doubt it should be expected to be supported in C++, even if it "works" in other contexts – Piotr Skotnicki Mar 19 '15 at 11:19

1 Answers1

2
const char *const TestClass<T>::kSyncString[] = {
  [TestClass<T>::SYNC_TYPE]  = "sync type",
  [TestClass<T>::ASYNC_TYPE]  = "async type",
};

This initialization manner is called designated initializer, which C99 has. Since C++11 doesn't have this feature, gcc has this feature as extension.

I find it in the onlinedocs. It is in "6 Extensions to the C Language Family", not "7 Extensions to the C++ Language". So, I guess gcc can't process C++ feature (TestClass<T>::SYNC_TYPE - template and scope-operator) in C extension. (just guessing >o<) Anyway, it seems certain that it's the compiler-extension defeat.

Community
  • 1
  • 1
ikh
  • 10,119
  • 1
  • 31
  • 70