c++ - 在 C++20 中使用 typename 需要/概念?

标签 c++ c++20

请考虑以下 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;
};
现在两种配方(你的原始配方和我的替代配方)都会产生 falseWorksWithA<BadArg> .

关于c++ - 在 C++20 中使用 typename 需要/概念?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66209966/

相关文章:

c++ - C指针指向包含对齐的C结构的C++类的对齐问题

C++:字符串和 union Bison

c++ - C++ 简明检查元素是否属于临时集

C++ 使用 constexpr 使放置新对齐的存储可初始化

c++ - 为什么 int 对象和函数类型之间存在歧义?

c++ - C++不等待输入

c++ - 使用 C++20 在编译时检查容器中是否存在重复元素

c++ - 使用聚合初始化模拟默认函数参数是否有任何陷阱?

c++ - 使用 C++20 using-enum-declaration 进行二义性名称查找

c++ - 预处理器宏和 std::source_location 之间的区别