首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C++20中使用typename需要/ concept?

在C++20中使用typename需要/ concept?
EN

Stack Overflow用户
提问于 2021-02-15 22:35:36
回答 1查看 105关注 0票数 6

请考虑以下C++20程序:

代码语言:javascript
复制
#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,但我在1 1中观察到了。谁是对的?为什么?

代码语言:javascript
复制
$ clang++ --version
clang version 10.0.0-4ubuntu1 
$ clang++ test.cc -std=c++20
$ ./a.out 
1
1
EN

回答 1

Stack Overflow用户

发布于 2021-02-15 22:46:11

这里的概念只是将类型命名为A<BadArg>,它不会触发它的实例化。这里没有任何东西导致A<BadArg>::X的实例化,这将是病态的。

如果是这样的话,你就不会得到false了,你会得到一个格式错误的程序。例如,你有没有做过:

代码语言:javascript
复制
template<typename T>
constexpr bool WorksWithA = requires { A<T>{}; };

然后,WorksWithA<BadArg>将触发A<BadArg>的实例化,该实例化将尝试查找BadArg::X,这在直接的替换上下文之外现在是一个失败。不是false,编译错误。

如果你想要一个false的结果,你必须将A模板限制在现有的类型上:

代码语言:javascript
复制
template <typename T>
    requires requires { typename T::X; }
struct A {
    using X = typename T::X;
};

现在,这两个公式(您的原始公式和我的替代公式)都将为WorksWithA<BadArg>生成false

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66209966

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档