【发布时间】:2018-04-19 01:20:27
【问题描述】:
假设给定 C++17 的 if 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 似乎是合理的,并且将采用 if constexpr 的 else 分支。与此相反,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 中的错误,还是预期的行为?
【问题讨论】:
-
请注意,使用单独的类(非原始类)也会产生硬错误:wandbox.org/permlink/QIBdPOsxSVK5AD9r
-
AFAIK gcc 的概念实现是基于 Concepts TS 的,它只被接受了一些修改,包括限制使用
requires子句的位置。在P0266 中单独提出了允许这样做。我认为我们还不能回答您的问题。 -
-
我的问题似乎与stackoverflow.com/q/53493715/893406有关,您的回答是这个硬错误是设计使然。
-
它开始使用最新的 GCC 版本:wandbox.org/permlink/QIBdPOsxSVK5AD9r
标签: c++ c++-concepts c++20