c-部分专注于错误类型的非类型模板参数

考虑以下:

template <unsigned >
struct uint_ { };

template <class >
struct X {
    static constexpr bool value = false;
};

template <int I> // NB: int, not unsigned
struct X<uint_<I>> {
    static constexpr bool value = true;
};

int main() {
    static_assert(X<uint_<0>>::value, "!");
}

clang编译代码,gcc不会.

但是,在以下高度相关的示例中:

template <unsigned >
struct uint_ { };

template <int I> // NB: int, not unsigned
void foo(uint_<I> ) { }

int main() {
    foo(uint_<0>{} );
}

两种编译器都拒绝,没有匹配的函数调用foo. gcc的行为是一致的,clang的行为是不一致的-因此一个或另一个编译器对于一个或两个示例都有错误.哪个编译器正确?

最佳答案
GCC是正确的. [temp.deduct.type]/17

If P has a form that contains <i>, and if the type of the
corresponding value of A differs from the type of i, deduction fails.

转载注明原文:c-部分专注于错误类型的非类型模板参数 - 代码日志