简体   繁体   中英

Can I define a static constexpr data member only for certain specializations?

The following program works just fine.

#include <iostream>
#include <type_traits>

template <typename DummyT = void>
struct wrapper
{
  static_assert(std::is_same<void, DummyT>::value, "Only void, please");
  static constexpr char text[] = "some string constant";
};

template <typename DummyT>
constexpr char wrapper<DummyT>::text[];

int
main()
{
  std::cout << wrapper<>::text << '\n';
}

However, when I only define wrapper::text for wrapper<void> ,

template <>
constexpr char wrapper<void>::text[];

then GCC 5.3.0 gives me this linker error

/tmp/ccnGx3EP.o: In function `main':
main.cxx:(.text+0x5): undefined reference to `wrapper<void>::text'
collect2: error: ld returned 1 exit status

and Clang 3.7.1 gives me this error.

main.cxx:12:31: error: declaration of constexpr static data member 'text' requires an initializer
constexpr char wrapper<void>::text[];
                              ^
1 error generated.

I'm wondering why it isn't sufficient to provide a definition only for the specialization that is actually used. Not that it would be terribly useful as a static constexpr member has to be initialized inside the class definition so I cannot specialize it in the definition anyway but I might want to leave it undefined.

Easily:

template <typename DummyT = void>
struct wrapper
{
  static_assert(std::is_same<void, DummyT>::value, "Only void, please");
};

template <>
struct wrapper<void>
{
  static constexpr char text[] = "some string constant";
};

constexpr char wrapper<void>::text[];

Both wrapper<> and wrapper<void> will work while any other parameter will fail with a static_assert .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM