【发布时间】:2020-03-27 18:09:31
【问题描述】:
我有代码可以简化成这样的:
#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);
}
这无法使用带有--std=c++17 的 g++ 9.3 进行编译,并出现错误:
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;
| ^~~~
这不是我所期望的。我希望尝试在template <typename T> typename dependent<T>::type foo(const T& x) 中用bool 替换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 开始不应该发生这种情况。什么给了?
【问题讨论】:
-
该示例旨在说明按词汇顺序进行并在遇到故障时停止。因为替换到第一个默认模板参数失败,所以根本不替换第二个默认模板参数。
-
该示例演示了我正在寻找的解决方法,但我无法通过查看它来理解:-)