我在 C++ 20 '概念'中的 模板方法中问了一个非常类似的问题,我再次问的原因是因为 AI 服务说它是 C++ 标准的一部分,尽管 gcc (11.4.0) 和 clang (14.0.0) 不编译。
这是我要编译的代码,几乎与生成的一个人工智能服务相同:
#include <concepts>
template <typename T>
concept C = requires(T a) {
{ a.m1(std::declval<int>()) } -> std::convertible_to<int>;
template <std::unsigned_integral U> {
a.m2(std::declval<int>())
} -> std::convertible_to<int>;
};
template <C t> void f(t &p_t) { p_t.m1(3); }
class S {
public:
int m1(int i) { return 2 * i; }
template <std::unsigned_integral t> int m2(t p_t) { return p_t; }
};
int main() {
S _s;
f(_s);
}
代码无法按照报告
template <std::unsigned_integral U>
进行编译:Expected expression
。
那么,C++20 中是否支持概念中的模板方法,但尚未实现;或者我的代码是错误的;或者AI服务生成了错误的代码?
requires 子句中不能有模板。但你的概念可以有第二个模板参数:
template<typename T, typename U>
concept C = requires(T a, U in)
{
{ a.m1(int{}) } -> std::convertible_to<int>;
std::unsigned_integral<U>; // force U to be unsigned_integral here
{ a.template m2<U>(U{}) } -> std::convertible_to<int>;
};
因为概念不允许进行声音训练请参阅此处,您需要明确检查
U
是否也是std::unsigned_integral
。
现在
C
有两个模板参数,因此你的函数 f
也需要是两个参数的模板:
template<std::unsigned_integral U, C<U> t>
void f(t& p_t) { p_t.m1(3); } // call with f<unsigned>(_s);
但是当您知道调用 f 时您拥有哪种无符号类型时,这应该不是问题。如果您在函数中不需要
m2
,您可以决定为 U
提供默认类型,例如std::unsigned_integral U = unsigned
。但如果无论如何都不需要组合的话,那么拆分你的概念可能是明智的。