下面的程序工作得很好。我可以爲某些專業化定義靜態constexpr數據成員嗎?
#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
和鏘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.
我想知道爲什麼僅僅爲實際使用的專業化提供一個定義是不夠的。並不是說它會非常有用,因爲 constexpr
成員必須在class
定義中初始化,所以我無法將它定義在定義中,但我可能想讓它不確定。
顯式特化有效地替換了主模板中的聲明/定義。 –
@ T.C。我在假設靜態數據成員的類內初始化不是一個定義。所以不應該將模板體中的聲明+初始化應用於數據成員的所有類 - 模板的隱式實例化? –
@ T.C。是的,我的直覺是對的:http://coliru.stacked-crooked.com/a/597464c14d48071f。所以,他的問題是他不能提供一個定義的專業化,而不提供一個初始化,因爲後者只聲明專業化。但是如果他做了後者,他會有兩個初始值。 –