У меня есть код, который я могу упростить до следующего вида:
#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;
| ^~~~
This это не то, что я ожидал. Я ожидаю, что попытка заменить bool
на T
в template <typename T> typename dependent<T>::type foo(const T& x)
будет неудачей, а не ошибкой. Кажется, 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. Что дает?