最小限の例では、少し複雑になり、親テンプレートのパラメータを推定するために乱用です:は、それがクラスのスコープ内の関数をconstexprのためにポインタを渡すときに私が得た
struct A { };
template <int>
struct Parent { };
template <int N>
constexpr int operator*(A, Parent<N>*) { return N; }
template <class T>
using ptr = T*;
template <int>
struct Other { };
template <int N>
struct Kid: Parent<N> {
static Other<A{} * ptr<Kid>{}> o;
};
int main() {
Kid<2>{};
}
[gcc]は[clang]は文句を言い、何の問題もなく、コードをコンパイルします
:私たちは、コードビットを変更したときより不条理取得するにはprog.cc:7:15: note: candidate template ignored: could not match 'Parent' against 'Kid'
constexpr int operator*(A, Parent<N>*) { return N; }
:Kid
問題に対してParent
のマッチングについて
struct A { };
template <int>
struct Parent { };
template <int N>
constexpr int operator*(A, Parent<N>*) { return N; }
template <class T>
using ptr = T*;
template <int>
struct Other { };
template <int N>
struct Kid: Parent<N> {
static constexpr int s = A{} * ptr<Kid>{};
};
int main() {
Other<Kid<2>::s>{};
}
[clang]もコードをコンパイルします。だから...バグか、私は狂っていくのですか?
100%の回答では助けになることはできませんが、一般的に 'gcc'は' clang'よりも容認されていますが、後者はもっと厳密に標準に従っています。私はそれがここの場合だと思うでしょう。ただし、インテル®コンパイラーもこのコードを受け入れます。 – davmac