在C ++ 20中使用类型名需要/概念吗? [英] Using typename in C++20 requires / concept?

查看:53
本文介绍了在C ++ 20中使用类型名需要/概念吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下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中使用类型名需要/概念吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆