问题描述
请考虑以下C ++ 20程序:
Please consider the following C++20 program:
#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?
我期望输出为 1 0
,但是我在clang 1 1
中观察到.谁是对的,为什么?
I was expecting the output to be 1 0
but I observe in 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
推荐答案
这里的概念只是命名类型 A< BadArg>
,它并没有做任何事情来触发它的实例化.这里没有任何东西会导致格式不正确的 A< BadArg> :: X
的实例化.
The concept here is just naming the type A<BadArg>
, it doesn't do anything to trigger instantiation of it. Nothing here leads to the instantiation of A<BadArg>::X
which would be ill-formed.
如果 did 仍然正确,那么无论如何您都不会得到 false
,您会得到格式错误的程序.例如,您是否做过:
If it did though, then you wouldn't get false
anyway, you'd get an ill-formed program. For instance, had you done:
template<typename T>
constexpr bool WorksWithA = requires { A<T>{}; };
然后 WorksWithA< BadArg>
将触发 A< BadArg>
的实例化,该实例将尝试查找 BadArg :: X
,即现在是替代替代环境之外的失败.不是 false
,编译错误.
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. Not false
, compile error.
如果想要的结果为 false
,则必须将 A
模板限制为现有类型:
If you want a result that's false
, you'll have to constrain the A
template on the type existing:
template <typename T>
requires requires { typename T::X; }
struct A {
using X = typename T::X;
};
现在两种形式(您的原始和我的替代品)都将为 WorksWithA< BadArg>
生成 false
.
And now both formulations (your original and my substitute) would yield false
for WorksWithA<BadArg>
.
这篇关于在C ++ 20中使用类型名需要/概念吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!