下面的簡單代碼或Godbolt上的簡單代碼不能用 clang 編譯,但可以用 gcc 和 Visual Studio 編譯。
decltype(foo(t))當 SFINAE 因 clang、gcc 和 Visual Studio 失敗時,baz(T t)不評估尾隨回傳型別。
但是,當 requires 子句因 clang 失敗時,仍會評估decltype(foo(t))尾隨回傳型別。bar(T t)當要求子句在 gcc 和 Visual Studio 中失敗時,不評估尾隨回傳型別。哪個編譯器在這方面是正確的?
謝謝你。
#include <utility>
#include <type_traits>
template<typename T>
auto foo(T) {
static_assert(std::is_integral<T>::value); // clang error: static_assert failed due to requirement 'std::is_integral<double>::value'
return 5;
}
template<typename T> requires std::is_integral<T>::value
auto bar(T t) -> decltype(foo(t)) {
return foo(t);
}
template<typename T> requires (!std::is_integral<T>::value)
auto bar(T) {
return 1.5;
}
template<typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
auto baz(T t) -> decltype(foo(t)) {
return foo(t);
}
template<typename T, std::enable_if_t<!std::is_integral<T>::value>* = nullptr>
auto baz(T) {
return 1.5;
}
int main()
{
bar(5.); // fails with clang, works with gcc and VS
baz(5.); // works with clang, gcc and VS
}
uj5u.com熱心網友回復:
這是CWG 2369,clang 似乎尚未實施。
該問題中的示例(現在可以在[temp.deduct.general]/5中找到)不能在 clang 上編譯,但可以在 gcc 上編譯。
template <class T> struct Z {
typedef typename T::x xx;
};
template <class T> concept C = requires { typename T::A; };
template <C T> typename Z<T>::xx f(void *, T); // #1
template <class T> void f(int, T); // #2
struct A {} a;
struct ZZ {
template <class T, class = typename Z<T>::xx> operator T *();
operator int();
};
int main() {
ZZ zz;
f(1, a); // OK, deduction fails for #1 because there is no conversion from int to void*
f(zz, 42); // OK, deduction fails for #1 because C<int> is not satisfied
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/484066.html
