c++ - 在 C++20 中使用 typename 需要 / 概念?
问题描述
请考虑以下 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
解决方案
这里的概念只是命名 type A<BadArg>
,它不做任何事情来触发它的实例化。这里没有任何东西会导致其实例化格式A<BadArg>::X
不正确。
如果确实如此,那么无论如何你都不会得到false
,你会得到一个格式错误的程序。例如,您是否做过:
template<typename T>
constexpr bool WorksWithA = requires { A<T>{}; };
ThenWorksWithA<BadArg>
将触发 which 的实例化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>
推荐阅读
- javascript - 如何在命令行中传递参数以运行纱线脚本
- java - Java Spring refcursor queries slows down
- hp-nonstop - Is there a grep equivalent in TACL on HP-Nonstop?
- tor - 如何在 mac 上安装 obfs4proxy?
- java - 第二次尝试打开Shell时如何修复Widget配置错误?
- php - 在共享主机上托管 Laravel elasticsearch 项目
- r - R中排序多列的最高和最低100个观察值
- javascript - 我如何在反应中使用材料 ui 库从我的自动完成框中获得选择
- java - 使用 Xades4J 签署示例 XML 时出错:ReferenceNotInitializedException:无法解析具有 ID 的元素
- pandas - 如何使用 Python 为转置数据框中的每个单元格实现 if-else 语句