从属类型中出错时的 SFINAE 会导致意外的硬错误



我有代码可以简化为这样的东西:

#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的非官方参考中的示例:

替换按词法顺序进行,并在遇到故障时停止。

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上遇到这种情况,但"保证不会在 C++14 发生"位似乎表明这不应该发生在 C++14 开始。什么给?

问题是dependent<T>type,但可能格式不正确,导致硬故障。

你可以让dependentSFINAE 友好:

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;
};

演示

最新更新