以下程序运作正常。
#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';
}
但是,当我只为wrapper::text
定义wrapper<void>
时,
template <>
constexpr char wrapper<void>::text[];
然后GCC 5.3.0给我这个链接器错误
/tmp/ccnGx3EP.o: In function `main':
main.cxx:(.text+0x5): undefined reference to `wrapper<void>::text'
collect2: error: ld returned 1 exit status
和Clang 3.7.1给了我这个错误。
main.cxx:12:31: error: declaration of constexpr static data member 'text' requires an initializer
constexpr char wrapper<void>::text[];
^
1 error generated.
我想知道为什么仅仅为实际使用的专业化提供定义是不够的。并不是说它非常有用,因为static
constexpr
成员必须在class
定义中初始化,所以我无法在定义中专门化它,但我可能想要保留它未定义。
答案 0 :(得分:0)
轻松:
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[];
wrapper<>
和wrapper<void>
都有效,而其他任何参数都会因static_assert
而失败。