请考虑以下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,但我在1 1中观察到了。谁是对的?为什么?
$ clang++ --version
clang version 10.0.0-4ubuntu1
$ clang++ test.cc -std=c++20
$ ./a.out
1
1发布于 2021-02-15 22:46:11
这里的概念只是将类型命名为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;
};现在,这两个公式(您的原始公式和我的替代公式)都将为WorksWithA<BadArg>生成false。
https://stackoverflow.com/questions/66209966
复制相似问题