[英]Using typename in C++20 requires / concept?
Please consider the following C++20 program:请考虑以下 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;
}
Is this ill-formed?这是病态的吗? And if not, what should the output be?
如果不是,output 应该是什么?
I was expecting the output to be 1 0
but I observe in clang 1 1
.我期待 output 为
1 0
但我在 clang 1 1
中观察到。 Who's right and why?谁是对的,为什么?
$ clang++ --version
clang version 10.0.0-4ubuntu1
$ clang++ test.cc -std=c++20
$ ./a.out
1
1
The concept here is just naming the type A<BadArg>
, it doesn't do anything to trigger instantiation of it.这里的概念只是命名类型
A<BadArg>
,它不做任何事情来触发它的实例化。 Nothing here leads to the instantiation of A<BadArg>::X
which would be ill-formed.这里没有任何东西会导致
A<BadArg>::X
的实例化,这将是格式错误的。
If it did though, then you wouldn't get false
anyway, you'd get an ill-formed program.如果确实如此,那么无论如何你都不会出错,你会得到一个格式
false
的程序。 For instance, had you done:例如,您是否做过:
template<typename T>
constexpr bool WorksWithA = requires { A<T>{}; };
Then WorksWithA<BadArg>
would trigger instantiation of A<BadArg>
which would try to look up BadArg::X
, which is now a failure outside of the immediate context of substitution.然后
WorksWithA<BadArg>
将触发A<BadArg>
的实例化,该实例化将尝试查找BadArg::X
,这现在是直接替换上下文之外的失败。 Not false
, compile error.不是
false
,编译错误。
If you want a result that's false
, you'll have to constrain the A
template on the type existing:如果您想要一个
false
的结果,则必须将A
模板限制在现有类型上:
template <typename T>
requires requires { typename T::X; }
struct A {
using X = typename T::X;
};
And now both formulations (your original and my substitute) would yield false
for WorksWithA<BadArg>
.现在两种公式(您的原始公式和我的替代公式)都会为
WorksWithA<BadArg>
产生false
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.