SFINAE on Error in Dependent Type 导致意外的硬错误
SFINAE on Error in Dependent Type causes unexpected hard error
我有可以简化为如下代码的代码:
#include <type_traits>
template <typename T>
struct dependent
{
using type = typename T::type;
};
template <typename T>
typename dependent<T>::type
foo(const T& x);
bool foo(bool x) { return x; }
int main()
{
foo(true);
}
使用 g++ 9.3 编译失败 --std=c++17
错误:
test.cpp: In instantiation of 'struct dependent<bool>':
test.cpp:11:1: required by substitution of 'template<class T> typename dependent<T>::type foo(const T&) [with T = bool]'
test.cpp:17:13: required from here
test.cpp:6:11: error: 'bool' is not a class, struct, or union type
6 | using type = typename T::type;
| ^~~~
这不是我所期望的。我希望尝试用 bool
替换 template <typename T> typename dependent<T>::type foo(const T& x)
中的 T
会失败,这不是错误。似乎 SFINAE 不适合我,但我不知道为什么。
来自 SFINAE 上的非官方参考中的示例:
Substitution proceeds in lexical order and stops when a failure is encountered.
template <typename A>
struct B { using type = typename A::type; };
template <
class T,
class = typename T::type, // SFINAE failure if T has no member type
class U = typename B<T>::type // hard error if T has no member type
// (guaranteed to not occur as of C++14)
> void foo (int);
我在 class U = typename B<T>::type
上遇到这种情况,但是 "guaranteed to not occur as of C++14" 位似乎表明从 C++14 开始这不应该发生。给出了什么?
问题是 dependent<T>
有 type
,但那个可能格式不正确导致硬故障。
你可能会让 dependent
SFINAE 变得友好:
template <typename T, typename Enabler = void>
struct dependent
{
};
template <typename T>
struct dependent<T, std::void_t<typename T::type>>
{
using type = typename T::type;
};
我有可以简化为如下代码的代码:
#include <type_traits>
template <typename T>
struct dependent
{
using type = typename T::type;
};
template <typename T>
typename dependent<T>::type
foo(const T& x);
bool foo(bool x) { return x; }
int main()
{
foo(true);
}
使用 g++ 9.3 编译失败 --std=c++17
错误:
test.cpp: In instantiation of 'struct dependent<bool>':
test.cpp:11:1: required by substitution of 'template<class T> typename dependent<T>::type foo(const T&) [with T = bool]'
test.cpp:17:13: required from here
test.cpp:6:11: error: 'bool' is not a class, struct, or union type
6 | using type = typename T::type;
| ^~~~
这不是我所期望的。我希望尝试用 bool
替换 template <typename T> typename dependent<T>::type foo(const T& x)
中的 T
会失败,这不是错误。似乎 SFINAE 不适合我,但我不知道为什么。
来自 SFINAE 上的非官方参考中的示例:
Substitution proceeds in lexical order and stops when a failure is encountered.
template <typename A> struct B { using type = typename A::type; }; template < class T, class = typename T::type, // SFINAE failure if T has no member type class U = typename B<T>::type // hard error if T has no member type // (guaranteed to not occur as of C++14) > void foo (int);
我在 class U = typename B<T>::type
上遇到这种情况,但是 "guaranteed to not occur as of C++14" 位似乎表明从 C++14 开始这不应该发生。给出了什么?
问题是 dependent<T>
有 type
,但那个可能格式不正确导致硬故障。
你可能会让 dependent
SFINAE 变得友好:
template <typename T, typename Enabler = void>
struct dependent
{
};
template <typename T>
struct dependent<T, std::void_t<typename T::type>>
{
using type = typename T::type;
};