[英]Partially specialized template static constexpr in template class
(一個玩具,最小的不工作示例)
下一個代碼不能用 cpp20/17 編譯:
template<typename TSomeTemplate>
struct A
{
static constexpr size_t B = 1;
template<typename T, typename... Ts>
static constexpr size_t C = 4;
template<typename T>
static constexpr size_t C<T> = B;
};
int main()
{
A<int>::C<int>;
return 0;
}
關於結構中的最后一行,出現“表達式未計算為常量”的錯誤。 但是,它確實以完全專業化或不引用 B 的方式進行編譯:
template<typename TSomeTemplate>
struct Works
{
static constexpr size_t B = 1;
template<typename T, typename... Ts>
static constexpr size_t C = 4;
template<>
static constexpr size_t C<int> = B;
};
template<typename TSomeTemplate>
struct AlsoWorks
{
static constexpr size_t B = 1;
template<typename T, typename... Ts>
static constexpr size_t C = 4;
template<typename T>
static constexpr size_t C<T> = 2;
};
為什么會這樣? 我怎樣才能使第一個結構工作?
你不能這樣專攻,你可以使用 SFINAE 或者你可以嘗試類似的東西:
template<typename TSomeTemplate>
struct A
{
static constexpr size_t B = 1;
template<typename T, typename... Ts>
static constexpr size_t C = sizeof...(Ts) == 0 ? B : 4;
};
我能夠通過添加模板關鍵字來編譯您的代碼。
template<typename TSomeTemplate>
struct A
{
static constexpr size_t B = 1;
template<typename T, typename... Ts>
static constexpr size_t C = 4;
template<typename T>
static constexpr size_t C<T> = B;
};
int main()
{
A<int>::template C<int>;
return 0;
}
正如這里所引用的。
類似地,在模板定義中,不是當前實例化成員的依賴名稱不被視為模板名稱,除非使用了消歧關鍵字 template 或除非它已被建立為模板名稱:
我看不出代碼有什么問題。
template<typename T>
static constexpr size_t C<T> = B;
這是C
變量模板的部分特化,在 class scope 內部也是允許的。 它也比主模板更專業。
B
顯然是一個常量表達式,因為它之前已被定義為constexpr
變量。 即使它僅被聲明為const
,它仍然可以在常量表達式中使用(因為它是整數類型)。 編譯器將其拒絕為不是常量表達式是錯誤的。
似乎這里只有一些編譯器錯誤在起作用(GCC 似乎不喜歡 class scope 中的變量模板部分特化,MSVC 似乎對B
的 constness 有問題。Z9375884CF4ED31C834A626C32 不抱怨)
GCC 和 MSVC 拒絕代碼是錯誤的,因為程序格式正確。
B
是一個常量表達式,可以在C
的部分特化期間用作初始化器。 這是一個 msvc 錯誤,此處報告為:
使用 constexpr static 數據成員作為初始化程序時,MSVC 拒絕有效代碼。
此外,我們可以為C
提供部分專業化(如您所做的那樣)。 這是一個 gcc 錯誤報告為:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.