配列サイズの妥当性に基づいて特化しようとしています:
// base template
template<int p, typename T = void>
struct absolute {
operator int () const { return 0; }
};
// positive case template
template<int p>
struct absolute<p, typename std::void_t<int[p]>> {
operator int () const { return p; }
};
// negative case template
template<int p>
struct absolute<p, typename std::void_t<int[-p]>> {
operator int () const { return -p; }
};
int main() {
std::cout << absolute<5>() << std::endl;
std::cout << absolute<-5>() << std::endl;
std::cout << absolute<0>() << std::endl;
}
問題#1:
上記のコードはgccでうまく動作しますが、clangでコンパイルできません。
Clangがエラーを生成:テンプレート構造体 'absolute'の再定義
誰が正しいのですか?
問題#2:
gccとclangの両方(clangをゲームに戻すために否定的な特殊化を削除する場合)の両方でabsolute<0>()
、ベーステンプレートを選択する理由が明確ではありません。何も間違ってありますとint[0]
してだけでなく、std::void_t<int[0]>
より専門ているように見えるそれは:
// base template
template<int p, typename T = void>
struct absolute {
operator int () const { return -1; }
};
// positive case template
template<int p>
struct absolute<p, typename std::void_t<int[p]>> {
operator int () const { return p; }
};
int main() {
std::cout << absolute<5>() << std::endl; // 5
std::cout << absolute<0>() << std::endl; // -1, why not 0?
}
そして...基本テンプレートが実装なしで宣言されている場合:
// base template
template<int p, typename T = void>
struct absolute;
gccとclangの両方がコンパイルに失敗し、呼び出しで不完全な型を無効に使用したことを報告しました:absolute<0>()
。特殊なケースに当てはまるようですが。
何故ですか?
int[0]
ISO C ++標準timsong-cpp.github.io/cppwp/n4659/dcl.array#1によって禁止されています "その値はゼロより大きくなければなりません"
template<int p> struct absolute<p, typename std::void_t<int[p]>>
そしてtemplate<int p> struct absolute
それは複製ではありませんか?