假设,给定 C++17if constexpr
和 Concepts TS(例如,在最近的 gcc 版本中),我们想检查模板函数中的类型是否具有嵌套类型:
#include <iostream>
struct Foo { using Bar = int; };
template<typename T>
void doSmth(T)
{
if constexpr (requires { typename T::Bar; })
std::cout << "has nested! " << typename T::Bar {} << std::endl;
else
std::cout << "no nested!" << std::endl;
}
int main()
{
doSmth(Foo {});
//doSmth(0);
}
概念文档很少,所以我可能弄错了,但似乎就是这样(现场示例在Wandbox上)。
doSmth
现在让我们考虑取消注释另一个调用时会发生什么。期望 requires 子句的计算结果为 似乎是合理的false
,并且将采用 the 的else
分支if constexpr
。与此相反,gcc 使这是一个硬错误:
prog.cc: In instantiation of 'void doSmth(T) [with T = int]':
prog.cc:17:13: required from here
prog.cc:8:5: error: 'int' is not a class, struct, or union type
if constexpr (requires { typename T::Bar; })
^~
这是 gcc 中的错误,还是预期的行为?