请考虑以下 C++20 程序:
#include <iostream>
template<typename T>
struct A {
using X = typename T::X;
};
template<typename T>
constexpr bool WorksWithA = requires { typename A<T>; };
struct GoodArg {
using X = int;
};
struct BadArg {
};
int main() {
std::cout << WorksWithA<GoodArg> << std::endl;
std::cout << WorksWithA<BadArg> << std::endl;
}
这是畸形的吗?如果不是,输出应该是什么?我原以为输出是
1 0
但我在 clang 中观察 1 1
.谁是对的,为什么?$ clang++ --version
clang version 10.0.0-4ubuntu1
$ clang++ test.cc -std=c++20
$ ./a.out
1
1
最佳答案
这里的概念只是命名类型 A<BadArg>
,它不会做任何事情来触发它的实例化。这里没有任何内容导致 A<BadArg>::X
的实例化这将是格式错误的。
如果确实如此,那么您将不会收到 false
无论如何,你会得到一个格式错误的程序。例如,你是否做过:
template<typename T>
constexpr bool WorksWithA = requires { A<T>{}; };
然后WorksWithA<BadArg>
将触发 A<BadArg>
的实例化哪个会尝试查找 BadArg::X
,这现在是替换的直接上下文之外的失败。不是 false
,编译错误。如果你想要一个结果是
false
,你必须限制 A
现有类型的模板:template <typename T>
requires requires { typename T::X; }
struct A {
using X = typename T::X;
};
现在两种配方(你的原始配方和我的替代配方)都会产生 false
为 WorksWithA<BadArg>
.
关于c++ - 在 C++20 中使用 typename 需要/概念?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66209966/